package com.jeequan.jeepay.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.applyment.ChannelFeeCalModel;
import com.jeequan.jeepay.core.model.applyment.PaywayFee;
import com.jeequan.jeepay.core.utils.AmountUtil;
import com.jeequan.jeepay.core.utils.DateKit;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.service.mapper.OrderProfitSettRecordMapper;
import com.jeequan.jeepay.service.mapper.PayOrderMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.MutablePair;
import org.apache.commons.lang3.tuple.MutableTriple;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * <p>
 * 订单分润结算记录 服务实现类
 * </p>
 *
 * @author [mybatis plus generator]
 * @since 2022-03-22
 */
@Service
@Slf4j
public class OrderProfitSettRecordService extends ServiceImpl<OrderProfitSettRecordMapper, OrderProfitSettRecord> {

    @Autowired
    private PayOrderMapper payOrderMapper;
    @Autowired
    private RateConfigService rateConfigService;
    @Autowired
    private AgentInfoService agentInfoService;
    @Autowired
    private MchInfoService mchInfoService;
    @Autowired
    private PayInterfaceConfigService payInterfaceConfigService;
    @Autowired
    private InfoAccountService infoAccountService;
    @Autowired
    private RefundOrderService refundOrderService;
    @Autowired
    private PayInterfaceDefineService payInterfaceDefineService;
    @Autowired
    private TransferOrderService transferOrderService;
    @Autowired
    private MchAppService mchAppService;

    /**
     * 计算分润（支付订单）
     * <p>
     * 佣金计算： 服务商V  底价 0.2%   一级服务商A1 (0.3%)， 二级服务商 A2 (0.35%) ,  商户M(所属A1) (0.6%)
     * <p>
     * 支付1000为例：
     * 商户入账金额 =  订单支付金额 -（订单支付金额 X 商户费率） = 1000 - 6 = 994
     * <p>
     * A2佣金  商户M费用 - A2费率费用  = 6 - 3.5 = 2.5
     * <p>
     * A1佣金  A2费率费用 - A1费率费用 = 3.5 - 3 = 0.5
     * <p>
     * 平台利润： 商户费率费用 - 所有服务商利润 - 渠道商底价 =  6 - 2.5 - 0.5 - 2 = 1 （也等于： 一级服务商费用 - 底价）
     * <p>
     * 返回是否 实时计算
     */
    @Transactional
    public boolean insertProfitByPayOrder(String payOrderId, Byte calType) {

        Byte orderInfoMchType = null;
        String orderInfoWayCode = null;
        String orderInfoIsvNo = null;
        String orderInfoIfCode = null;
        String orderInfoOrderAgentNo = null;
        String orderInfoMchAppId = null;
        String orderInfoMchNo = null;
        Long orderInfoAmount = null;
        String mchApplyId = null;
        String settleType = null;
        PaywayFee paywayFeeByMch = null;
        PaywayFee paywayFeeByIsv = null;
        Integer range = null;
        String mccCode = null;
        String entryType = null;
        Integer settHoldDay = 0;
        // 支付订单
        if (calType == OrderProfitSettRecord.CAL_TYPE_PAY_ORDER) {

            PayOrder payOrder = payOrderMapper.selectById(payOrderId);
            orderInfoMchType = payOrder.getMchType();
            orderInfoWayCode = payOrder.getWayCode();
            orderInfoIsvNo = payOrder.getIsvNo();
            orderInfoIfCode = payOrder.getIfCode();
            orderInfoOrderAgentNo = payOrder.getAgentNo();
            orderInfoMchAppId = payOrder.getAppId();
            orderInfoMchNo = payOrder.getMchNo();
            orderInfoAmount = payOrder.getAmount();
            mchApplyId = payOrder.getMchExtNo();
            settleType = payOrder.getSettleType();
            // 普通商户， 无需计算
            if (CS.MCH_TYPE_NORMAL == orderInfoMchType) {
                return false;
            }
            // 查询服务商的配置信息
            PayInterfaceConfig payInterfaceConfig = payInterfaceConfigService.getByInfoIdAndIfCode(CS.SYS_ROLE_TYPE.ISV, orderInfoIsvNo, orderInfoIfCode);
            if (payInterfaceConfig.getSettHoldDay() == -1) {
                return false;
            }

            MchAppEntity mchApp = mchAppService.getById(orderInfoMchAppId);

            // 商户配置费率
            paywayFeeByMch = rateConfigService.getPaywayFeeByMch(orderInfoIfCode, orderInfoWayCode, mchApplyId, mchApp.getRange(), mchApp.getMccCode(), orderInfoIsvNo);

            // 平台底价
            paywayFeeByIsv = rateConfigService.getPaywayFeeByIsvCost(orderInfoIfCode, orderInfoWayCode, orderInfoIsvNo, mchApp.getRange(), mchApp.getMccCode());

            range = mchApp.getRange();
            mccCode = mchApp.getMccCode();
            settHoldDay = payInterfaceConfig.getSettHoldDay();
        } else if (calType == OrderProfitSettRecord.CAL_TYPE_TRANS_ORDER) { // 转账订单
            TransferOrderEntity transferOrder = transferOrderService.getById(payOrderId);
            if (transferOrder.getTransferType().equals(TransferOrderEntity.TRANSFER_TYPE_CZ)) {
                // 充值订单
                return false;
            }

            orderInfoWayCode = CS.PAY_WAY_CODE.TRANSFER;
            orderInfoIsvNo = transferOrder.getIsvNo();
            orderInfoIfCode = transferOrder.getIfCode();
            orderInfoOrderAgentNo = transferOrder.getAgentNo();
            orderInfoMchNo = transferOrder.getMchNo();
            orderInfoAmount = transferOrder.getAmount();
            mchApplyId = transferOrder.getMchExtNo();
            // 如果转账订单不包含费率配置， 说明没有配置， 那么无需计算。
            if (StringUtils.isEmpty(transferOrder.getMchFeeRate()) || transferOrder.getMchOrderFeeAmount() == null) {
                return false;
            }
            paywayFeeByMch = rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByMchApp(orderInfoMchNo), CS.SYS_ROLE_TYPE.MCH, orderInfoIfCode, null, null, orderInfoIsvNo, true).get(transferOrder.getEntryType());

            paywayFeeByIsv = rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByIsvCost(orderInfoIsvNo), CS.SYS_ROLE_TYPE.ISV, orderInfoIfCode, null, null, orderInfoIsvNo, true).get(transferOrder.getEntryType());

            entryType = transferOrder.getEntryType();
        }

        // 外部订单支付方式， 无需计算
        if (CS.PAY_WAY_CODE.OUT_TRADE.equals(orderInfoWayCode)) {
            return false;
        }

        // 服务商的底价
        List<MutablePair<String, PaywayFee>> paywayFeeByAgentList = new ArrayList<>();

        // 商户的所属服务商
        if (StringUtils.isNotEmpty(orderInfoOrderAgentNo)) {
            // 全部的服务商号  三级 --》 二级 --》 顶级
            List<String> allAgentNo = agentInfoService.queryAllParentAgentNo(orderInfoOrderAgentNo);
            Collections.reverse(allAgentNo);

            for (String agentNo : allAgentNo) {
                PaywayFee paywayFeeByAgent = null;
                if (calType == OrderProfitSettRecord.CAL_TYPE_PAY_ORDER) {
                    paywayFeeByAgent = rateConfigService.getPaywayFeeByAgent(orderInfoIfCode, orderInfoWayCode, agentNo, range, mccCode, orderInfoIsvNo);
                } else {
                    paywayFeeByAgent = rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByAgent(agentNo), CS.SYS_ROLE_TYPE.AGENT, orderInfoIfCode, null, null, orderInfoIsvNo, true).get(entryType);
                }
                paywayFeeByAgentList.add(MutablePair.of(agentNo, paywayFeeByAgent));
            }
        }

        // 计算佣金
        List<OrderProfitSettRecord> result = this.calAllRoleProfit(orderInfoMchNo, orderInfoAmount, paywayFeeByMch, paywayFeeByIsv, paywayFeeByAgentList, calType, payOrderId);


        this.recordListOrderByInfo(result); // 排序


        //D0结算垫资手续费
        if (StringUtils.isNotBlank(settleType) && CS.SETTLEMENT_TYPE.D0.equals(settleType)) {
            // 商户配置费率
            PaywayFee d0Fee = rateConfigService.getPaywayFeeByMch(orderInfoIfCode, CS.SETTLEMENT_TYPE.D0, mchApplyId, range, mccCode, orderInfoIsvNo);
            // 平台底价
            PaywayFee d0IsvFee = rateConfigService.getPaywayFeeByIsvCost(orderInfoIfCode, CS.SETTLEMENT_TYPE.D0, orderInfoIsvNo, range, mccCode);
            List<OrderProfitSettRecord> dzList = this.calAllRoleProfit(orderInfoMchNo, orderInfoAmount, d0Fee, d0IsvFee, paywayFeeByAgentList, OrderProfitSettRecord.CAL_TYPE_DZ_ORDER, payOrderId);
            result.addAll(dzList);
        }
        // 计算结算日期   比如当前时间为2022-04-08 20:00:00 支付成功， 结算日期为1天， 那么预计结算时间为： 2022-04-09 00:00:00 （执行日期以定时任务跑批时间为准）
        Date entryTime = DateUtil.offsetDay(DateKit.getBegin(new Date()), settHoldDay).toJdkDate();
        for (OrderProfitSettRecord orderProfitSettRecord : result) {
            orderProfitSettRecord.setEntryTime(entryTime); //预计入账日期(比如在途转钱包)
        }
        // 入库
        saveBatch(result);

        // 动账 ( 在途余额 )
        for (OrderProfitSettRecord orderProfitSettRecord : result) {

            // 商户的也在list中， 但是 profit为 0 不会在商户侧动账。
            infoAccountService.changeAmountBySettProfit(orderProfitSettRecord, InfoAccountHistory.OP_ACCOUNT_TYPE_AUDIT_PROFIT);
        }

        // 0 表示实时结算
        return settHoldDay <= 0;

    }

    /**
     * 将订单在途金额 转换为 钱包余额
     * 已订单为维度， 若有异常，该笔订单所有角色将不可正常结算。
     */
    @Transactional
    public void profit2BalanceAmount(String payOrderId, Byte calType) {

        Date nowTime = new Date();

        LambdaQueryWrapper<OrderProfitSettRecord> condition = OrderProfitSettRecord.gw()
                .eq(OrderProfitSettRecord::getPayOrderId, payOrderId)
                .eq(OrderProfitSettRecord::getEntryState, CS.NO)
                .le(OrderProfitSettRecord::getEntryTime, nowTime);

        // 如果是 转账订单， 那么仅查询转账的，   支付查询全部（包含： 支付和退款）
        if (calType == OrderProfitSettRecord.CAL_TYPE_TRANS_ORDER) {
            condition.in(OrderProfitSettRecord::getCalType, Arrays.asList(OrderProfitSettRecord.CAL_TYPE_TRANS_ORDER));
        } else {
            condition.in(OrderProfitSettRecord::getCalType, Arrays.asList(OrderProfitSettRecord.CAL_TYPE_PAY_ORDER, OrderProfitSettRecord.CAL_TYPE_REFUND_ORDER, OrderProfitSettRecord.CAL_TYPE_DZ_ORDER));
        }

        // 20230112：  1. 先更新 OrderProfitSettRecord 表 （ 按照 插入的顺序， 否则：  顺序不一致导致死锁的产生 （insert 为全表锁 ） ）
        //             2. 更新 info_account表数据。
        OrderProfitSettRecord updateRecord = new OrderProfitSettRecord();
        updateRecord.setTaskTime(nowTime); //处理任务时间
        //  updateRecord.setEntryState(CS.YES); //  此处不更新 结算状态，  仅仅更新 处理任务时间 ，  为了拿到 表锁
        update(updateRecord, condition);

        // 需要更新的map集合 // 20220330 更改此处， 目的： 当出现退款订单时， 查询的数据排序不可控，若退款负值在前， 那么更新到在途时可能是负数， 导致验证失败。 程序报错。 （虽然整体最后结果一定是正确的）
        // 此处将所有的入账金额进行了汇总， 结果一定的 >= 0 的数据。
        Map<String, OrderProfitSettRecord> updateRoleMap = new HashMap<>();

        // 查询出全部的订单分润逻辑
        list(condition).stream().forEach(r -> {

            // 定义唯一的主键  infoId + infoType
            String key = r.getInfoId() + "_" + r.getInfoType();
            OrderProfitSettRecord item = updateRoleMap.get(key);
            if (item == null) {
                updateRoleMap.put(key, r);
            } else {

                // 金额的累加 （ 比如 订单金额 - 退款金额 ）
                item.setCalProfitAmount(item.getCalProfitAmount() + r.getCalProfitAmount());
                updateRoleMap.put(key, item);
            }
        });

        List<OrderProfitSettRecord> updateRecordList = new ArrayList<>(updateRoleMap.values());
        this.recordListOrderByInfo(updateRecordList); // 排序

        // 所有需要更新的订单数据
        updateRecordList.forEach(orderProfitSettRecord -> {

            orderProfitSettRecord.setCalType(calType); // 订单佣金计算 or 转账

            // 累加 钱包余额
            infoAccountService.changeAmountBySettProfit(orderProfitSettRecord, InfoAccountHistory.OP_ACCOUNT_TYPE_BALANCE);

            // 扣减  在途
            orderProfitSettRecord.setCalProfitAmount(0 - orderProfitSettRecord.getCalProfitAmount());
            infoAccountService.changeAmountBySettProfit(orderProfitSettRecord, InfoAccountHistory.OP_ACCOUNT_TYPE_AUDIT_PROFIT);

        });

        // 20230112：  1. 先更新 OrderProfitSettRecord 表 （ 按照 插入的顺序， 否则：  顺序不一致导致死锁的产生 （insert 为全表锁 ） ）
        //             2. 更新 info_account表数据。
        OrderProfitSettRecord updateRecord2 = new OrderProfitSettRecord();
        updateRecord2.setEntryState(CS.YES); //已结算
        updateRecord2.setTaskTime(new Date()); //处理任务时间

        boolean updateFlag2 = update(updateRecord2, condition);
        if (!updateFlag2) {
            throw new BizException("更新分润订单异常！");
        }

    }


    /**
     * 退款退分润
     * <p>
     * <p>
     * 100元 ，  商户费率 10%  共计费用10元
     * 服务商： 2%     利润： 8元
     * <p>
     * <p>
     * 退款50元， 还剩50，   商户实际费用 = （ 100 -50） X 10% = 5  ,  本条应减：5 - 8 = -3
     * <p>
     * <p>
     * 又退款 30元，还剩20，   商户实际费用 = （ 100 -50 - 30 ） X 10% = 2 ， 本条应减： -3
     * <p>
     * 本条应减 =  实际利润/费用  - （订单计算佣金/费用  - 全部的上次退款计算）
     * <p>
     * <p>
     * <p>
     * 商户实际费用 = 首次订单费用 - （本次之前的全部退还的费用[正数]） - 当次计算退还费用 X
     * 当次计算退还费用X  = 首次订单费用 - （本次之前的全部退还的费用[正数]）  - 商户实际费用
     * <p>
     * <p>
     * 返回格式：    MutableTriple<手续费快照, 商户实际手续费, 本次退还手续费>
     **/
    @Transactional
    public MutableTriple<String, Long, Long> insertProfitByRefundOrder(String refundOrderId) {

        // 退款订单
        RefundOrder refundOrder = refundOrderService.getById(refundOrderId);

        // 原始支付订单
        PayOrder dbPayOrder = payOrderMapper.selectById(refundOrder.getPayOrderId());

        // 订单的实际收款金额 = 首次收款 - 全部退款金额
        Long calBaseAmount = dbPayOrder.getAmount() - dbPayOrder.getRefundAmount();

        // 本次退款金额
        Long currentRefundAmount = refundOrder.getRefundAmount();

        // 获取手续费计算模式
        PayInterfaceDefine payInterfaceDefine = payInterfaceDefineService.getById(dbPayOrder.getIfCode());
        ChannelFeeCalModel channelFeeCalModel = ChannelFeeCalModel.getByDefault(payInterfaceDefine == null ? null : payInterfaceDefine.getChannelFeeCalModel());

        // 是否分开计算模式
        boolean isSplitCalModel = ChannelFeeCalModel.FEE_CAL_MODEL_SPLIT_PAY_REFUND_AMOUNT.equals(channelFeeCalModel.getFeeCalModel());
        // 是否基于最新收单金额计算（原逻辑）
        boolean isBaseFinalModel = !isSplitCalModel;

        // 普通商户
        if (dbPayOrder.getMchType() == CS.MCH_TYPE_NORMAL) {

            // 查询费率
            PaywayFee paywayFee = rateConfigService.queryCreateOrderPaywayFee(dbPayOrder.getMchExtNo(), dbPayOrder.getIsvNo(), dbPayOrder.getAppId(), dbPayOrder.getIfCode(), dbPayOrder.getWayCode());

            // 原逻辑 || 不是单笔费率，只能按照原逻辑计算！！！
            if (isBaseFinalModel || !PaywayFee.FEE_TYPE_SINGLE.equals(paywayFee.getFeeType())) {
                return PaywayFee.convert2MutableTriple(paywayFee.calFeeAndSnapshot(calBaseAmount), dbPayOrder.getMchFeeAmount());
            }


            // 分开计算模式

            // 本次退还手续费金额（退款金额 X 费率）： 本次退回手续费 >  商家实际手续费表示不足以扣除金额，直接扣除商家手续费。  最终商家手续费为 0 。
            MutablePair<String, Long> resultBySplit = paywayFee.calFeeAndSnapshot(currentRefundAmount);
            Long currentRefundFeeAmount = resultBySplit.right;
            if (currentRefundFeeAmount > dbPayOrder.getMchFeeAmount()) {
                currentRefundFeeAmount = dbPayOrder.getMchFeeAmount();
            }

            resultBySplit.setRight(dbPayOrder.getMchFeeAmount() - currentRefundFeeAmount); // 商家最终手续费
            return PaywayFee.convert2MutableTriple(resultBySplit, dbPayOrder.getMchFeeAmount());
        }


        // 查询全部的分佣数据

        // 商户的分佣快照
        PaywayFee mchPaywayFee = null; // 商户的费率计算方式模版
        OrderProfitSettRecord mchRecord = null;
        Long mchAllRefundProfit = 0L; // 商户全部退款利润 （一定是负数）
        Long mchAllRefundFee = 0L; // 商户全部退款费用  （一定是负数）

        // 运营平台的三方支付网关的入账金额
        OrderProfitSettRecord platformInAccountRecord = null;
        Long platformInAccountAllRefundProfit = 0L; // 全部退款利润 （一定是负数）
        Long platformInAccountAllRefundFee = 0L; // 全部退款费用  （一定是负数）

        // 平台利润账户
        OrderProfitSettRecord platformProfitRecord = null;
        Long platformProfitAllRefundProfit = 0L; // 全部退款利润 （一定是负数）
        Long platformProfitAllRefundFee = 0L; // 全部退款费用  （一定是负数）

        // 服务商的快照
        Map<String, OrderProfitSettRecord> agentRecordMap = new HashMap<>();
        Map<String, Long> agentAllRefundProfitMap = new HashMap<>();
        Map<String, Long> agentAllRefundFeeMap = new HashMap<>();


        // 查询全部的订单分润记录
        List<OrderProfitSettRecord> allList = list(OrderProfitSettRecord.gw()
                .eq(OrderProfitSettRecord::getPayOrderId, dbPayOrder.getPayOrderId())
                .in(OrderProfitSettRecord::getCalType, Arrays.asList(OrderProfitSettRecord.CAL_TYPE_PAY_ORDER, OrderProfitSettRecord.CAL_TYPE_REFUND_ORDER))
        );

        // 查询数据不存在： 可能是订单分润表未记录， 也可能是设置的 -1， 那么也需要更新订单表记录。  查询的为最新的费率信息。
        if (allList.isEmpty()) {
            log.error("订单退款业务： 计算分润数据异常, allList is empty ！ 可能导致订单手续费计算有误。  order={} ", dbPayOrder.getPayOrderId());

            // 查询费率
            PaywayFee paywayFee = rateConfigService.queryCreateOrderPaywayFee(dbPayOrder.getMchExtNo(), dbPayOrder.getIsvNo(), dbPayOrder.getAppId(), dbPayOrder.getIfCode(), dbPayOrder.getWayCode());

            // 原逻辑 || 不是单笔费率，只能按照原逻辑计算！！！
            if (isBaseFinalModel || !PaywayFee.FEE_TYPE_SINGLE.equals(paywayFee.getFeeType())) {
                return PaywayFee.convert2MutableTriple(paywayFee.calFeeAndSnapshot(calBaseAmount), dbPayOrder.getMchFeeAmount());
            }


            // 分开计算模式

            // 本次退还手续费金额（退款金额 X 费率）： 本次退回手续费 >  商家实际手续费表示不足以扣除金额，直接扣除商家手续费。  最终商家手续费为 0 。
            MutablePair<String, Long> resultBySplit = paywayFee.calFeeAndSnapshot(currentRefundAmount);
            Long currentRefundFeeAmount = resultBySplit.right;
            if (currentRefundFeeAmount > dbPayOrder.getMchFeeAmount()) {
                currentRefundFeeAmount = dbPayOrder.getMchFeeAmount();
            }

            resultBySplit.setRight(dbPayOrder.getMchFeeAmount() - currentRefundFeeAmount); // 商家最终手续费
            return PaywayFee.convert2MutableTriple(resultBySplit, dbPayOrder.getMchFeeAmount());
        }

        for (OrderProfitSettRecord r : allList) {
            // 支付订单计算佣金的记录
            if (r.getCalType() == OrderProfitSettRecord.CAL_TYPE_PAY_ORDER) {

                if (CS.SYS_ROLE_TYPE.MCH.equals(r.getInfoType())) {

                    mchRecord = r;

                } else if (CS.INFO_ID_ENUM.PLATFORM_INACCOUNT.equals(r.getInfoId()) && CS.SYS_ROLE_TYPE.PLATFORM.equals(r.getInfoType())) {

                    platformInAccountRecord = r;

                } else if (CS.INFO_ID_ENUM.PLATFORM_PROFIT.equals(r.getInfoId()) && CS.SYS_ROLE_TYPE.PLATFORM.equals(r.getInfoType())) {

                    platformProfitRecord = r;

                } else if (CS.SYS_ROLE_TYPE.AGENT.equals(r.getInfoType())) {

                    agentRecordMap.put(r.getInfoId(), r);
                }

            } else { // 退款退佣

                if (CS.SYS_ROLE_TYPE.MCH.equals(r.getInfoType())) {

                    mchAllRefundProfit = mchAllRefundProfit + r.getCalProfitAmount();
                    mchAllRefundFee = mchAllRefundFee + r.getCalFeeAmount();

                } else if (CS.INFO_ID_ENUM.PLATFORM_INACCOUNT.equals(r.getInfoId()) && CS.SYS_ROLE_TYPE.PLATFORM.equals(r.getInfoType())) {

                    platformInAccountAllRefundProfit = platformInAccountAllRefundProfit + r.getCalProfitAmount();
                    platformInAccountAllRefundFee = platformInAccountAllRefundFee + r.getCalFeeAmount();

                } else if (CS.INFO_ID_ENUM.PLATFORM_PROFIT.equals(r.getInfoId()) && CS.SYS_ROLE_TYPE.PLATFORM.equals(r.getInfoType())) {

                    platformProfitAllRefundProfit = platformProfitAllRefundProfit + r.getCalProfitAmount();
                    platformProfitAllRefundFee = platformProfitAllRefundFee + r.getCalFeeAmount();

                } else if (CS.SYS_ROLE_TYPE.AGENT.equals(r.getInfoType())) {

                    if (agentAllRefundProfitMap.get(r.getInfoId()) == null) {
                        agentAllRefundProfitMap.put(r.getInfoId(), 0L);
                    }
                    if (agentAllRefundFeeMap.get(r.getInfoId()) == null) {
                        agentAllRefundFeeMap.put(r.getInfoId(), 0L);
                    }

                    agentAllRefundProfitMap.put(r.getInfoId(), (agentAllRefundProfitMap.get(r.getInfoId())) + r.getCalProfitAmount());
                    agentAllRefundFeeMap.put(r.getInfoId(), (agentAllRefundFeeMap.get(r.getInfoId())) + r.getCalFeeAmount());

                }
            }
        }


        if (mchAllRefundFee == null) {
            return null;
        }

        // 以下为 ：  --   重新计算订单分润   --

        // 服务商的底价
        List<MutablePair<String, PaywayFee>> paywayFeeByAgentList = new ArrayList<>();

        // 商户的所属服务商
        if (StringUtils.isNotEmpty(dbPayOrder.getAgentNo())) {
            // 全部的服务商号  三级 --》 二级 --》 顶级
            List<String> allAgentNo = agentInfoService.queryAllParentAgentNo(dbPayOrder.getAgentNo());
            Collections.reverse(allAgentNo);
            for (String agentNo : allAgentNo) {
                paywayFeeByAgentList.add(MutablePair.of(agentNo, agentRecordMap.get(agentNo).getInfoPaywayFeeDetail().toJavaObject(PaywayFee.class)));
            }
        }

        if (mchRecord == null || platformProfitRecord == null) { // 业务验证， 解决 fortify检测问题
            log.error("mchRecord = {}, platformProfitRecord = {}", mchRecord, platformProfitRecord);
            throw new BizException("数据异常");
        }


        // 商户计算模版
        mchPaywayFee = mchRecord.getInfoPaywayFeeDetail().toJavaObject(PaywayFee.class);

        // 如果不是单笔费率模式， 即时设置了：FEE_CAL_MODEL_SPLIT_PAY_REFUND_AMOUNT 也不生效。
        if (!PaywayFee.FEE_TYPE_SINGLE.equals(mchPaywayFee.getFeeType())) {
            isBaseFinalModel = true;
            isSplitCalModel = false;
        }


        // 全部数据
        List<OrderProfitSettRecord> result;

        if (isSplitCalModel) { // 支付宝模式

            // 全部服务商本次退款之前的 全部手续费
            Map<String, Long> allAgentFeeBeforeCurrentMap = new HashMap<>();

            // 全部服务商本次退款之前的 全部利润
            Map<String, Long> allAgentProfitBeforeCurrentMap = new HashMap<>();

            for (String agentNo : agentRecordMap.keySet()) {

                Long agentAllRefundFee = agentAllRefundFeeMap.get(agentNo); // 可能为空
                allAgentFeeBeforeCurrentMap.put(agentNo, (agentRecordMap.get(agentNo).getCalFeeAmount() + (agentAllRefundFee == null ? 0L : agentAllRefundFee)));

                Long agentAllRefundProfit = agentAllRefundProfitMap.get(agentNo); // 可能为空
                allAgentProfitBeforeCurrentMap.put(agentNo, (agentRecordMap.get(agentNo).getCalProfitAmount() + (agentAllRefundProfit == null ? 0L : agentAllRefundProfit)));
            }

            // 服务商手续费 - 退款手续费(负数)
            Long allIsvFeeBeforeCurrent = platformInAccountRecord.getCalFeeAmount() + platformInAccountAllRefundFee;

            result = this.calAllRoleProfitBySplitPayRefundAmount(
                    dbPayOrder.getMchNo(), currentRefundAmount, dbPayOrder,
                    mchRecord.getInfoPaywayFeeDetail().toJavaObject(PaywayFee.class), platformProfitRecord.getInfoPaywayFeeDetail().toJavaObject(PaywayFee.class), paywayFeeByAgentList,
                    allAgentFeeBeforeCurrentMap, allAgentProfitBeforeCurrentMap, allIsvFeeBeforeCurrent,
                    (platformInAccountRecord.getCalProfitAmount() + platformInAccountAllRefundProfit),
                    (platformProfitRecord.getCalProfitAmount() + platformProfitAllRefundProfit)
            );

        } else { // 原逻辑

            //  商户实际费用(F) = 首次订单费用(A) - （本次之前的全部退还的费用[正数]）(B) - 当次计算退还费用(X)
            //  那么可得：  当次计算退还费用(X)   = 首次订单费用(A) - （本次之前的全部退还的费用[正数]）(B)  - 商户实际费用(F)
            //  X = A - B -F
            // 注意 【当次计算退还费用X】 是一个正数， 保存到DB需要取负数
            result = this.calAllRoleProfit(dbPayOrder.getMchNo(), calBaseAmount, mchRecord.getInfoPaywayFeeDetail().toJavaObject(PaywayFee.class),
                    platformProfitRecord.getInfoPaywayFeeDetail().toJavaObject(PaywayFee.class), paywayFeeByAgentList, OrderProfitSettRecord.CAL_TYPE_REFUND_ORDER, dbPayOrder.getPayOrderId());

        }

        for (OrderProfitSettRecord record : result) {

            record.setRid(null);
            record.setCreatedAt(null);
            record.setUpdatedAt(null);
            record.setRefundOrderId(refundOrderId); // 退款订单号
            record.setCalBaseAmount(refundOrder.getRefundAmount()); // 本次退款金额
            record.setEntryState(mchRecord.getEntryState());

            // 未入账, 记录预计结算日期即可
            if (mchRecord.getEntryState() == CS.NO) {

                record.setEntryTime(mchRecord.getEntryTime());
                record.setTaskTime(null);

            } else { // 已入账， 那么需要记录当前日期， 并且直接扣减钱包余额

                record.setEntryTime(new Date());
                record.setTaskTime(record.getEntryTime());
            }

            if (isSplitCalModel) { // 分开计算模式, 在获取List时已经做了处理。  此处无需处理。

            } else { // 原逻辑

                if (CS.SYS_ROLE_TYPE.MCH.equals(record.getInfoType())) {

                    record.setCalProfitAmount(mchRecord.getCalProfitAmount() + mchAllRefundProfit - record.getCalProfitAmount());
                    record.setCalFeeAmount(mchRecord.getCalFeeAmount() + mchAllRefundFee - record.getCalFeeAmount());

                } else if (CS.INFO_ID_ENUM.PLATFORM_INACCOUNT.equals(record.getInfoId()) && CS.SYS_ROLE_TYPE.PLATFORM.equals(record.getInfoType())) {

                    if (platformInAccountRecord == null) { // 业务验证， 解决 fortify检测问题
                        throw new BizException("数据异常");
                    }

                    record.setCalProfitAmount(platformInAccountRecord.getCalProfitAmount() + platformInAccountAllRefundProfit - record.getCalProfitAmount());
                    record.setCalFeeAmount(platformInAccountRecord.getCalFeeAmount() + platformInAccountAllRefundFee - record.getCalFeeAmount());

                } else if (CS.INFO_ID_ENUM.PLATFORM_PROFIT.equals(record.getInfoId()) && CS.SYS_ROLE_TYPE.PLATFORM.equals(record.getInfoType())) {

                    record.setCalProfitAmount(platformProfitRecord.getCalProfitAmount() + platformProfitAllRefundProfit - record.getCalProfitAmount());
                    record.setCalFeeAmount(platformProfitRecord.getCalFeeAmount() + platformProfitAllRefundFee - record.getCalFeeAmount());

                } else if (CS.SYS_ROLE_TYPE.AGENT.equals(record.getInfoType())) {

                    // 避免为null
                    Long agentAllRefundProfit = agentAllRefundProfitMap.get(record.getInfoId()) == null ? 0L : agentAllRefundProfitMap.get(record.getInfoId());
                    Long agentAllRefundFee = agentAllRefundFeeMap.get(record.getInfoId()) == null ? 0L : agentAllRefundFeeMap.get(record.getInfoId());

                    record.setCalProfitAmount(agentRecordMap.get(record.getInfoId()).getCalProfitAmount() + agentAllRefundProfit - record.getCalProfitAmount());
                    record.setCalFeeAmount(agentRecordMap.get(record.getInfoId()).getCalFeeAmount() + agentAllRefundFee - record.getCalFeeAmount());
                }

            }

            // 结果一定是负数值
            record.setCalProfitAmount(0 - record.getCalProfitAmount());
            record.setCalFeeAmount(0 - record.getCalFeeAmount());

            if (record.getCalProfitAmount() > 0) {
                record.setCalProfitAmount(0L);
            }
            if (record.getCalFeeAmount() > 0) {
                record.setCalFeeAmount(0L);
            }

        }

        // 入库
        saveBatch(result);

        // 排序
        this.recordListOrderByInfo(result);

        // 动账 ( 在途余额 or  钱包 )
        for (OrderProfitSettRecord orderProfitSettRecord : result) {

            // 已结算
            if (mchRecord.getEntryState() == CS.YES) {
                // 商户的也在list中， 但是 profit为 0 不会在商户侧动账。
                infoAccountService.changeAmountBySettProfit(orderProfitSettRecord, InfoAccountHistory.OP_ACCOUNT_TYPE_BALANCE);

            } else { // 在途

                // 商户的也在list中， 但是 profit为 0 不会在商户侧动账。
                infoAccountService.changeAmountBySettProfit(orderProfitSettRecord, InfoAccountHistory.OP_ACCOUNT_TYPE_AUDIT_PROFIT);

            }
        }

        // 返回当前最新费率计算公式， 需要更新到订单上
        MutablePair<String, Long> feeAndSnapshot = mchRecord.getInfoPaywayFeeDetail().toJavaObject(PaywayFee.class).calFeeAndSnapshot(calBaseAmount);

        if (isBaseFinalModel) {
            return PaywayFee.convert2MutableTriple(feeAndSnapshot, dbPayOrder.getMchFeeAmount());
        }

        // 支付宝模式：

        // 获取本次退还费用。
        Long currentRefundMchFee = 0L;
        for (OrderProfitSettRecord orderProfitSettRecord : result) {
            if (CS.SYS_ROLE_TYPE.MCH.equals(orderProfitSettRecord.getInfoType())) {
                currentRefundMchFee = 0 - orderProfitSettRecord.getCalFeeAmount(); //取正数。
                break;
            }
        }
        return MutableTriple.of(feeAndSnapshot.getLeft(), AmountUtil.minZero(dbPayOrder.getMchFeeAmount() - currentRefundMchFee), AmountUtil.minZero(currentRefundMchFee));
    }


    /**
     * 计算分润 & 填充 OrderProfitSettRecord 基础数据
     * <p>
     * 部的服务商号  三级 --》 二级 --》 顶级
     **/
    public List<OrderProfitSettRecord> calAllRoleProfit(String mchNo, Long calBaseAmount, PaywayFee paywayFeeByMch, PaywayFee paywayFeeByIsv, List<MutablePair<String, PaywayFee>> paywayFeeByAgentList, Byte calType, String orderId) {

        List<OrderProfitSettRecord> result = new ArrayList<>();

        // 商户费率费用值
        Long feeByMch = paywayFeeByMch.calFee(calBaseAmount);
        if (calType == OrderProfitSettRecord.CAL_TYPE_PAY_ORDER) {
            Long minCalcAmount = paywayFeeByMch.calMinTradeAmt(calBaseAmount);
            if (calBaseAmount < minCalcAmount) {
                feeByMch = 0L;
            }
        }
        // 所有的服务商利润
        Long profitByAllAgent = 0L;
        // 商户数据
        OrderProfitSettRecord recordByMch = new OrderProfitSettRecord();
        recordByMch.setCalType(calType);
        recordByMch.setCalBaseAmount(calBaseAmount);
        recordByMch.setPayOrderId(orderId);
        recordByMch.setInfoId(mchNo);
        recordByMch.setInfoType(CS.SYS_ROLE_TYPE.MCH);
        recordByMch.setInfoName(mchInfoService.getById(mchNo).getMchShortName());
        recordByMch.setInfoPaywayFeeDetail((JSONObject) JSON.toJSON(paywayFeeByMch));
        recordByMch.setCalProfitAmount(0L); // 利润
        recordByMch.setCalFeeAmount(AmountUtil.minZero(feeByMch)); // 费率费用
        result.add(recordByMch);

        // 上一个的费率 ( 第一个为商户的费率 )
        Long prevFee = feeByMch;
        if (paywayFeeByAgentList != null) {

            for (MutablePair<String, PaywayFee> agentPaywayFeePair : paywayFeeByAgentList) {
                PaywayFee paywayFeeByAgent = agentPaywayFeePair.right;

                Long feeByCurrentAgent = paywayFeeByAgent.calFee(calBaseAmount); // 当前服务商的费率费用

                OrderProfitSettRecord record = new OrderProfitSettRecord();
                record.setCalType(calType);
                record.setCalBaseAmount(calBaseAmount);
                record.setPayOrderId(orderId);
                record.setInfoId(agentPaywayFeePair.left);
                record.setInfoType(CS.SYS_ROLE_TYPE.AGENT);
                record.setInfoName(agentInfoService.getById(agentPaywayFeePair.left).getAgentName());
                record.setInfoPaywayFeeDetail((JSONObject) JSON.toJSON(paywayFeeByAgent));
                record.setCalProfitAmount(AmountUtil.minZero(prevFee - feeByCurrentAgent)); // 利润
                record.setCalFeeAmount(AmountUtil.minZero(feeByCurrentAgent)); // 费率费用
                result.add(record);

                prevFee = feeByCurrentAgent; // 重置上一个
                profitByAllAgent += record.getCalProfitAmount(); // 累加服务商的利润
            }
        }

        Long feeByIsv = paywayFeeByIsv.calFee(calBaseAmount); // 底价

        // 平台利润
        OrderProfitSettRecord record = new OrderProfitSettRecord();
        record.setCalType(calType);
        record.setCalBaseAmount(calBaseAmount);
        record.setPayOrderId(orderId);
        record.setInfoId(CS.INFO_ID_ENUM.PLATFORM_PROFIT);
        record.setInfoType(CS.SYS_ROLE_TYPE.PLATFORM);
        record.setInfoName("运营平台");
        record.setInfoPaywayFeeDetail((JSONObject) JSON.toJSON(paywayFeeByIsv));
        record.setCalProfitAmount(AmountUtil.minZero(feeByMch - feeByIsv - profitByAllAgent)); // 利润
        record.setCalFeeAmount(AmountUtil.minZero(feeByIsv)); // 费率费用
        result.add(record);

        // 平台入账金额（不包含代理分润金额）
        OrderProfitSettRecord record2 = new OrderProfitSettRecord();
        record2.setCalType(calType);
        record2.setCalBaseAmount(calBaseAmount);
        record2.setPayOrderId(orderId);
        record2.setInfoId(CS.INFO_ID_ENUM.PLATFORM_INACCOUNT);
        record2.setInfoType(CS.SYS_ROLE_TYPE.PLATFORM);
        record2.setInfoName("运营平台");
        record2.setInfoPaywayFeeDetail((JSONObject) JSON.toJSON(paywayFeeByIsv));
        record2.setCalProfitAmount(AmountUtil.minZero(feeByMch - feeByIsv)); // 入账金额 =  商户费率费用 - 底价
        record2.setCalFeeAmount(AmountUtil.minZero(feeByIsv)); // 费率费用
        result.add(record2);

        return result;
    }


    /**
     * 计算订单数据， 收单金额和退款金额分开计算： SPLIT_PAY_REFUND_AMOUNT （ 支付宝模式 ）
     * 计算分润 & 填充 OrderProfitSettRecord 基础数据
     * <p>
     * 部的服务商号  三级 --》 二级 --》 顶级
     * <p>
     * 商家费率 0.65%，
     * 服务商费率 2%
     * <p>
     * 支付1000元 ， 退款700元
     * 1. ##支付##： 商家手续费    0.65% * 1000 = 【6.5元】
     * 1. ##支付##： 商家入账    【1000元】  - 【6.5元】 = 【93.5元】
     * <p>
     * 2. ##退款##： 商户手续费回退金额：  0.65% * 700  =【4.55元】
     * 2. ##退款##： 商户实际手续费： 【6.5元】 - 【4.55元】 = 【1.95元】
     * 2. ##退款##： 商户入账： 1000元 - 退款700元 -【1.95元】 = 298.05元
     * <p>
     * 服务商
     * 1. ##支付##： 服务商手续费： 0.2% * 1000 = 【2元】
     * 1. ##支付##： 服务商佣金：【6.5元】 - 【2元】 = 4.2元
     * <p>
     * 2. ##退款##： 服务商手续费回退金额： 700 * 0.2% = 【1.4元】
     * 2. ##退款##： 服务商手续费： 【2元】-【1.4元】 = 【0.6元】
     * 2. ##退款##： 服务商佣金 = 【1.95元】 - 【0.6元】 = 1.35元
     **/
    private List<OrderProfitSettRecord> calAllRoleProfitBySplitPayRefundAmount(String mchNo, Long currentRefundAmount,
                                                                               PayOrder dbPayOrder,
                                                                               PaywayFee paywayFeeByMch,
                                                                               PaywayFee paywayFeeByIsv,
                                                                               List<MutablePair<String, PaywayFee>> paywayFeeByAgentList,
                                                                               Map<String, Long> allAgentFeeBeforeCurrentMap,
                                                                               Map<String, Long> allAgentProfitBeforeCurrentMap,
                                                                               Long allIsvFeeBeforeCurrent,
                                                                               Long platformInAccountProfitBeforeCurrent,
                                                                               Long platformProfitProfitBeforeCurrent
    ) {

        List<OrderProfitSettRecord> result = new ArrayList<>();

        // 商家：本次退还手续费金额（退款金额 X 费率）： 本次退回手续费 >  商家实际手续费表示不足以扣除金额，直接扣除商家手续费。  最终商家手续费为 0 。
        Long currentRefundFeeAmountByMch = paywayFeeByMch.calFee(currentRefundAmount);
        if (currentRefundFeeAmountByMch > dbPayOrder.getMchFeeAmount()) {
            currentRefundFeeAmountByMch = dbPayOrder.getMchFeeAmount();
        }

        // 商家实际手续费
        Long feeAmountByMch = dbPayOrder.getMchFeeAmount() - currentRefundFeeAmountByMch;

        // 所有的服务商利润
        Long profitByAllAgent = 0L;

        // 商户数据
        OrderProfitSettRecord recordByMch = new OrderProfitSettRecord();
        recordByMch.setInfoId(mchNo);
        recordByMch.setInfoType(CS.SYS_ROLE_TYPE.MCH);
        recordByMch.setInfoName(mchInfoService.getById(mchNo).getMchShortName());
        recordByMch.setInfoPaywayFeeDetail((JSONObject) JSON.toJSON(paywayFeeByMch));
        recordByMch.setCalProfitAmount(0L); // 利润
        recordByMch.setCalFeeAmount(AmountUtil.minZero(currentRefundFeeAmountByMch)); // 费率费用
        result.add(recordByMch);

        // 上一个的手续费 ( 第一个为商户的手续费 )
        Long prevFee = dbPayOrder.getMchFeeAmount() - currentRefundFeeAmountByMch;
        if (paywayFeeByAgentList != null) {

            for (MutablePair<String, PaywayFee> agentPaywayFeePair : paywayFeeByAgentList) {
                PaywayFee paywayFeeByAgent = agentPaywayFeePair.right;

                // 当前服务商的 手续费退还费用 (本次)（退款金额 X 费率）
                Long currentRefundFeeAmountByCurrentAgent = paywayFeeByAgent.calFee(currentRefundAmount);

                // 服务商 本次退款之前的全部费用 ( 第一次费用 - （全部退款累加） )
                Long allAgentFeeBeforeCurrent = allAgentFeeBeforeCurrentMap.get(agentPaywayFeePair.left);

                // 本次手续费退还费用，不得高于 全部手续费
                if (currentRefundFeeAmountByCurrentAgent > allAgentFeeBeforeCurrent) {
                    currentRefundFeeAmountByCurrentAgent = allAgentFeeBeforeCurrent;
                }

                // 商户手续费不存在时， 服务商不可分佣
                if (feeAmountByMch <= 0) {
                    currentRefundFeeAmountByCurrentAgent = allAgentFeeBeforeCurrent;
                }

                // 当前服务商的实际手续费
                Long agentFeeByCurrentAgent = allAgentFeeBeforeCurrent - currentRefundFeeAmountByCurrentAgent;


                OrderProfitSettRecord record = new OrderProfitSettRecord();
                record.setInfoId(agentPaywayFeePair.left);
                record.setInfoType(CS.SYS_ROLE_TYPE.AGENT);
                record.setInfoName(agentInfoService.getById(agentPaywayFeePair.left).getAgentName());
                record.setInfoPaywayFeeDetail((JSONObject) JSON.toJSON(paywayFeeByAgent));

                // 当前的服务商 佣金
                Long currentAgentProfit = AmountUtil.minZero(prevFee - agentFeeByCurrentAgent);

                // 存入： 本次退还的佣金
                record.setCalProfitAmount(AmountUtil.minZero(allAgentProfitBeforeCurrentMap.get(agentPaywayFeePair.left) - currentAgentProfit));

                record.setCalFeeAmount(currentRefundFeeAmountByCurrentAgent); // 费率费用, 当前退的手续费， 正数
                result.add(record);

                prevFee = agentFeeByCurrentAgent; // 重置上一个
                profitByAllAgent += currentAgentProfit; // 累加服务商的利润 ( 服务商所有的利润总和 )
            }
        }

        // 服务商退还手续费
        Long refundFeeAmountByIsv = paywayFeeByIsv.calFee(currentRefundAmount);
        // 本次手续费退还费用，不得高于 全部手续费
        if (refundFeeAmountByIsv > allIsvFeeBeforeCurrent) {
            refundFeeAmountByIsv = allIsvFeeBeforeCurrent;
        }

        // 当前服务商的实际手续费
        Long feeByIsv = allIsvFeeBeforeCurrent - refundFeeAmountByIsv;

        // 平台利润
        OrderProfitSettRecord record = new OrderProfitSettRecord();
        record.setInfoId(CS.INFO_ID_ENUM.PLATFORM_PROFIT);
        record.setInfoType(CS.SYS_ROLE_TYPE.PLATFORM);
        record.setInfoName("运营平台");
        record.setInfoPaywayFeeDetail((JSONObject) JSON.toJSON(paywayFeeByIsv));

        // 利润 差值
        record.setCalProfitAmount(AmountUtil.minZero(platformProfitProfitBeforeCurrent - AmountUtil.minZero(feeAmountByMch - feeByIsv - profitByAllAgent)));
        record.setCalFeeAmount(AmountUtil.minZero(refundFeeAmountByIsv)); // 费率费用
        result.add(record);

        // 平台入账金额（不包含代理分润金额）
        OrderProfitSettRecord record2 = new OrderProfitSettRecord();
        record2.setInfoId(CS.INFO_ID_ENUM.PLATFORM_INACCOUNT);
        record2.setInfoType(CS.SYS_ROLE_TYPE.PLATFORM);
        record2.setInfoName("运营平台");
        record2.setInfoPaywayFeeDetail((JSONObject) JSON.toJSON(paywayFeeByIsv));

        // 利润 差值
        record2.setCalProfitAmount(AmountUtil.minZero(platformInAccountProfitBeforeCurrent - AmountUtil.minZero(feeAmountByMch - feeByIsv)));

        record2.setCalFeeAmount(AmountUtil.minZero(refundFeeAmountByIsv)); // 费率费用
        result.add(record2);

        return result;
    }


    /**
     * 查询支付订单的计算路基
     **/
    public PaywayFee findByPayOrderMchProfit(PayOrder dbPayOrder) {

        // 普通商户直接 查询费率
        if (dbPayOrder.getMchType() == CS.MCH_TYPE_NORMAL) {
            return rateConfigService.queryCreateOrderPaywayFee(dbPayOrder.getMchExtNo(), dbPayOrder.getIsvNo(), dbPayOrder.getAppId(), dbPayOrder.getIfCode(), dbPayOrder.getWayCode());
        }

        // 特约商户
        OrderProfitSettRecord mchRecord = this.getOne(OrderProfitSettRecord.gw()
                        .eq(OrderProfitSettRecord::getPayOrderId, dbPayOrder.getPayOrderId())
                        .eq(OrderProfitSettRecord::getCalType, OrderProfitSettRecord.CAL_TYPE_PAY_ORDER)
                        .eq(OrderProfitSettRecord::getInfoId, dbPayOrder.getMchNo())
                        .eq(OrderProfitSettRecord::getInfoType, CS.SYS_ROLE_TYPE.MCH)
                , false
        );

        // 如果仍然查询不到， 那么使用 当前的配置。
        if (mchRecord == null) {
            return rateConfigService.queryCreateOrderPaywayFee(dbPayOrder.getMchExtNo(), dbPayOrder.getIsvNo(), dbPayOrder.getAppId(), dbPayOrder.getIfCode(), dbPayOrder.getWayCode());
        }

        return mchRecord.getInfoPaywayFeeDetail().toJavaObject(PaywayFee.class);

    }

    /**
     * 查询到的结果集按照 infoId + infoType 排序。
     * 避免 更新时，  顺序不一致， 出现死锁的问题。
     **/
    public void recordListOrderByInfo(List<OrderProfitSettRecord> records) {

        if (records == null) {
            return;
        }
        Collections.sort(records, Comparator.comparing(o -> (o.getInfoId() + o.getInfoType())));
    }


}
