package com.crm.pay.service.impl;

import com.alibaba.fastjson.JSON;
import com.crm.pay.dao.mapper.FinanceDepositMapper;
import com.crm.pay.dao.mapper.GoldenOrderMapper;
import com.crm.pay.dao.repository.*;
import com.crm.pay.entity.FinanceDepositCallbackUpdateEntity;
import com.crm.pay.entity.FinanceDepositCallbackValidateUpdateEntity;
import com.crm.pay.service.*;
import com.crm.rely.backend.configuration.LocaleMessage;
import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.core.constant.EmailSendEnum;
import com.crm.rely.backend.core.constant.MapConstants;
import com.crm.rely.backend.core.constant.StatusConstants;
import com.crm.rely.backend.core.dto.base.BaseResultDto;
import com.crm.rely.backend.core.dto.base.PageDto;
import com.crm.rely.backend.core.dto.base.ResultWithPagerDto;
import com.crm.rely.backend.core.entity.system.email.SysEmailSendEntity;
import com.crm.rely.backend.core.entity.web.notice.record.WebNoticeRecordAndEmailMqEntity;
import com.crm.rely.backend.core.exception.PayValidatedException;
import com.crm.rely.backend.core.exception.ServiceException;
import com.crm.rely.backend.core.pojo.table.SysConfigTable;
import com.crm.rely.backend.model.constant.ConfigConstants;
import com.crm.rely.backend.model.constant.EmailTemplateConstants;
import com.crm.rely.backend.model.constant.PayConstants;
import com.crm.rely.backend.model.dto.finance.deposit.FinanceDepositDto;
import com.crm.rely.backend.model.entity.finance.deposit.FinanceDepositAddEntity;
import com.crm.rely.backend.model.entity.finance.deposit.FinanceDepositApproveEntity;
import com.crm.rely.backend.model.entity.finance.deposit.FinanceDepositDeleteEntity;
import com.crm.rely.backend.model.entity.finance.deposit.FinanceDepositSearchListEntity;
import com.crm.rely.backend.model.entity.sys.config.SysConfigAutolimitEntity;
import com.crm.rely.backend.model.entity.sys.config.SysConfigFinanceEntity;
import com.crm.rely.backend.model.pojo.table.*;
import com.crm.rely.backend.model.pojo.view.FinanceDepositView;
import com.crm.rely.backend.model.util.CustomInfoUtil;
import com.crm.rely.backend.service.EmailService;
import com.crm.rely.backend.service.MqSendService;
import com.crm.rely.backend.service.RedisService;
import com.crm.rely.backend.util.*;
import com.google.common.base.Strings;
import lombok.extern.log4j.Log4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.sql.Time;
import java.util.*;

/**
 * @description:
 * @author: houn
 * @create: 2019-05-05 20:31
 */
@Log4j
@Service
public class FinanceDepositServiceImpl implements FinanceDepositService {

    @Autowired
    private LocaleMessage localeMessage;

    @Autowired
    private FinanceDepositRepository financeDepositRepository;

    @Autowired
    private FinanceDepositMapper financeDepositMapper;

    @Autowired
    private SysConfigService sysConfigService;

    @Autowired
    private CustomLoginService customLoginService;

    @Autowired
    private CustomInfoRepository customInfoRepository;
    @Autowired
    private SysRemittanceChannelService sysRemittanceChannelService;
    @Autowired
    private SysChannelBankService sysChannelBankService;
    @Autowired
    private FinanceRateService financeRateService;
    @Autowired
    private GoldenOrderRepository goldenOrderRepository;
    @Autowired
    private GoldenOrderDetailsRepository goldenOrderDetailsRepository;
    @Autowired
    private GoldenGoodsRepository goldenGoodsRepository;
    @Autowired
    private GoldenOrderMapper goldenOrderMapper;
    @Autowired
    private RedisService redisService;
    @Autowired
    private SysRemittanceChannelRepository sysRemittanceChannelRepository;
    @Autowired
    private EmailService emailService;

    @Autowired
    private MqSendService mqSendService;

    /**
     * 保存入金信息
     *
     * @param balanceSaveEntity 入金实体
     * @return
     * @throws ServiceException
     * @throws PayValidatedException
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public FinanceDepositTable save(FinanceDepositAddEntity balanceSaveEntity)
            throws ServiceException, PayValidatedException {
        //获取入金通道
        SysRemittanceChannelTable channel =
                sysRemittanceChannelService.getSysRemittanceChannelByCode(balanceSaveEntity.getPayType());

        if (channel == null) {
            throw new ServiceException(PayConstants.FINANCE_DEPOSIT_CHANNEL_NOT_EMPTY);
        }
        return save(balanceSaveEntity, channel);
    }

    /**
     * 添加支付订单 以后有种支付方式 调用此方法
     *
     * @param balanceSaveEntity 入金保存信息
     * @param channel           入金通道信息
     * @return 支付url
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public FinanceDepositTable save(FinanceDepositAddEntity balanceSaveEntity, SysRemittanceChannelTable channel)
            throws ServiceException, PayValidatedException {
        return save(balanceSaveEntity, null, channel);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public FinanceDepositTable save(FinanceDepositAddEntity balanceSaveEntity, SysChannelBankTable sysChannelBankTable,
                                    SysRemittanceChannelTable channel)
            throws ServiceException, PayValidatedException {

        List<GoldenGoodsTable> goodsTables = goldenGoodsRepository.findAllByIdIn(balanceSaveEntity.getGoodIds());
        BigDecimal goodsPrice = BigDecimal.ZERO;
        for (GoldenGoodsTable goldenGoodsTable : goodsTables) {
            goodsPrice = goodsPrice.add(goldenGoodsTable.getGoodsPrice());
        }
        if (goodsPrice.compareTo(balanceSaveEntity.getAmount()) > 0 ) {
            throw new ServiceException("金额错误");
        }
        balanceSaveEntity.setAmount(goodsPrice);

        GoldenOrderDetailsTable detailsTable = goldenOrderMapper.getByCustomIdAndGoodsIdIn(balanceSaveEntity.getAddUser(), balanceSaveEntity.getGoodIds());
        if(detailsTable != null){
            throw new ServiceException("该产品已订购");
        }

        if (Strings.isNullOrEmpty(balanceSaveEntity.getCurrency())) {
            balanceSaveEntity.setCurrency(channel.getCurrency());
        }

        if (Strings.isNullOrEmpty(balanceSaveEntity.getTransformCurrency()) && sysChannelBankTable == null) {
            balanceSaveEntity.setTransformCurrency(channel.getTransformCurrency());
        }

        if (balanceSaveEntity.getActivityDeposit() == null) {
            balanceSaveEntity.setActivityDeposit(0);
        }
        if (balanceSaveEntity.getCustomId() == null && balanceSaveEntity.getAddUser() != null) {
            balanceSaveEntity.setCustomId(balanceSaveEntity.getAddUser());
        }

        //验证通道
        if (channel == null) {
            throw new ServiceException(PayConstants.FINANCE_DEPOSIT_CHANNEL_NOT_EMPTY);
        }

        //获取通道银行列表
        if (sysChannelBankTable == null) {
            sysChannelBankTable = getChannelBank(balanceSaveEntity, channel);
        }

        //判断支付系统中是否已经计算过金额 如果为空 则在这里计算
        BigDecimal transformAmount = getTransformAmount(balanceSaveEntity, channel);

        //验证订单金额是否在可入金额范围内
        validatedAmount(balanceSaveEntity, channel, sysChannelBankTable);

        //获取用户信息
        CustomInfoTable customInfoTable = getCustomInfo(balanceSaveEntity);

        //如果存在限制国家
        if (!Strings.isNullOrEmpty(channel.getCountrys())) {
            //分割国家
            List<String> countrys = Arrays.asList(channel.getCountrys().split(","));
            //判断国家 如果国家不在列表中 则拒绝
            if (!countrys.contains(customInfoTable.getCountry())) {
                throw ServiceException.exception(Constants.NOT_PERMIT);
            }

        }

        //如果存在省份限制
        if (!Strings.isNullOrEmpty(channel.getStates())) {
            //分割国家
            List<String> states = Arrays.asList(channel.getStates().split(","));
            //判断国家 如果国家不在列表中 则拒绝
            if (!states.contains(customInfoTable.getState())) {
                throw ServiceException.exception(Constants.NOT_PERMIT);
            }

        }

        //使用优惠码
        //MarketPromoCodeTable marketPromoCodeTable = usePromoCode(balanceSaveEntity, customInfoTable);

        //获取交易账号信息
        //CustomLoginTable customLoginTable = getCustomLogin(balanceSaveEntity);

        //验证是否信用可亏损
        //validatedCreditLoss(balanceSaveEntity, customLoginTable, marketPromoCodeTable);

        //设置入金实体的汇率
        setFinanceDepositAddRate(balanceSaveEntity, channel, sysChannelBankTable);


        Long cId = customInfoTable.getCId();

        //构建订单
        FinanceDepositTable financeDepositTable = new FinanceDepositTable();
        financeDepositTable.setCustomId(balanceSaveEntity.getCustomId());
        financeDepositTable.setCId(cId);
        financeDepositTable.setCallbackValidateMq(balanceSaveEntity.getCallbackValidateMq());
        if (balanceSaveEntity.getCallbackValidate() != null) {
            financeDepositTable.setCallbackValidate(2);
        } else {
            financeDepositTable.setCallbackValidate(null);
        }


        financeDepositTable.setDepositCurrency(balanceSaveEntity.getCurrency());
        //financeDepositTable.setPromoCode(balanceSaveEntity.getPromoCode());
        financeDepositTable.setBankMsg(balanceSaveEntity.getBankMsg());

        financeDepositTable.setCallbackMq(balanceSaveEntity.getCallbackMq());
        financeDepositTable.setExtParam(balanceSaveEntity.getExtParam());
        financeDepositTable.setAmount(balanceSaveEntity.getAmount());
        financeDepositTable.setStatus(PayConstants.APPLY_STATUS);
        financeDepositTable.setCallbackStatus(PayConstants.CALLBACE_PROCESSING_STATUS);
        financeDepositTable.setDepositStatus(PayConstants.MANAGER_PENDING_STATUS);
        financeDepositTable.setSubmitStatus(PayConstants.SUBMIT_PENDING_STATUS);
        financeDepositTable.setBankCode(balanceSaveEntity.getBankCode());
        financeDepositTable.setPayType(balanceSaveEntity.getPayType());
        financeDepositTable.setCurrency(balanceSaveEntity.getCurrency());
        financeDepositTable.setTransformCurrency(balanceSaveEntity.getTransformCurrency());
        financeDepositTable.setVoucherUrl(balanceSaveEntity.getVoucherUrl());
        financeDepositTable.setActivityDeposit(balanceSaveEntity.getActivityDeposit());
        if (balanceSaveEntity.getActivityDeposit() != null && balanceSaveEntity.getActivityDeposit().equals(1)) {
            financeDepositTable.setActivityStatus(1);
        } else {
            financeDepositTable.setActivityStatus(2);
        }


        if ("cny".equals(financeDepositTable.getTransformCurrency().toLowerCase())
                || "thb".equals(financeDepositTable.getTransformCurrency().toLowerCase())
                || "vnd".equals(financeDepositTable.getTransformCurrency().toLowerCase())) {
            transformAmount = transformAmount.divide(BigDecimal.ONE, 0, BigDecimal.ROUND_UP);
        }

        //获取订单用户名称
        String name = customInfoTable.getName();
        String orderNo = getOrderNo();
        //获取和处理入金平台订单
        Integer free = getFree(channel, sysChannelBankTable);
        BigDecimal depositAmount = getDepositAmount(financeDepositTable);
        if (free != null && free.compareTo(0) > 0) {
            depositAmount = depositAmount.multiply(new BigDecimal(1 - (free / 100.0)));
        }


        BigDecimal cnyAmount = getCnyAmount(balanceSaveEntity);

        financeDepositTable.setRate(balanceSaveEntity.getRate());
        financeDepositTable.setTransformAmount(transformAmount);
        financeDepositTable.setCny(cnyAmount);
        financeDepositTable.setDepositAmount(depositAmount.setScale(2, BigDecimal.ROUND_DOWN));
        financeDepositTable.setFree(free);
        financeDepositTable.setSerial(orderNo);
        financeDepositTable.setLogin(balanceSaveEntity.getLogin());
        financeDepositTable.setName(name);

        //计算过期时间 如果通道设置中过期时间为0或者null 标识用不过期 这里也就不设置设置为null或者设置时间戳为0
        if (channel.getExpire() != null & !channel.getExpire().equals(0)) {
            financeDepositTable.setExpireTime(DateUtil.operationMinute(channel.getExpire()));
        }

        financeDepositTable.setRemittanceChannelCode(channel.getCode());
        financeDepositTable.setRemittanceChannelName(channel.getName());
        financeDepositTable.setRemittanceChannelEnName(channel.getEnName());
        financeDepositTable.setRemittanceChannelIcon(channel.getIcon());
        financeDepositTable.setRemittanceChannelEnIcon(channel.getEnIcon());
        financeDepositTable.setRemittanceChannelCurrency(channel.getCurrency());
        financeDepositTable.setRemittanceChannelRequestUrl(channel.getRequestUrl());
        financeDepositTable.setRemittanceChannelProperty(channel.getProperty());
        financeDepositTable.setRemittanceChannelIntroduce(channel.getIntroduce());
        financeDepositTable.setRemittanceChannelEnIntroduce(channel.getEnIntroduce());

        financeDepositTable.setAddIp(balanceSaveEntity.getAddIp());
        financeDepositTable.setAddTime(balanceSaveEntity.getAddTime());
        financeDepositTable.setAddUser(balanceSaveEntity.getAddUser());
        financeDepositTable.setCountry(customInfoTable.getCountry());
        financeDepositTable.setCountryEnName(customInfoTable.getCountryEnName());
        financeDepositTable.setCountryName(customInfoTable.getCountryName());

        /*financeDepositTable.setSourceCode(customInfoTable.getSourceCode());
        financeDepositTable.setSourceName(customInfoTable.getSourceName());
        financeDepositTable.setSourceNameEn(customInfoTable.getSourceNameEn());*/

        //保存订单信息
        financeDepositRepository.save(financeDepositTable);

        GoldenOrderTable order = saveGoldenOrder(balanceSaveEntity, goodsTables, financeDepositTable, customInfoTable);

        if(channel.getExpire() != null){
            mqSendService.send(PayConstants.ORDER_DEPOSIT_EXPIRE, order, channel.getExpire() * 1000);
        }

        return financeDepositTable;
    }

    @Transactional(rollbackFor = Exception.class)
    public GoldenOrderTable saveGoldenOrder(FinanceDepositAddEntity balanceSaveEntity, List<GoldenGoodsTable> goodsTables
            ,FinanceDepositTable financeDepositTable, CustomInfoTable customInfoTable){
        GoldenOrderTable order = new GoldenOrderTable();
        order.setSerial(financeDepositTable.getSerial());
        order.setCustomId(financeDepositTable.getCustomId());
        order.setCId(financeDepositTable.getCId());
        order.setEmail(customInfoTable.getEmail());
        order.setAmount(financeDepositTable.getAmount());
        order.setCurrency(financeDepositTable.getCurrency());
        order.setTransformAmount(financeDepositTable.getTransformAmount());
        order.setTransformCurrency(financeDepositTable.getTransformCurrency());
        order.setAddTime(financeDepositTable.getAddTime());
        order.setStatus(PayConstants.ORDER_UP_PAY_STATUS);
        order.setPayName(balanceSaveEntity.getPayName());
        order.setPayPhone(balanceSaveEntity.getPayPhone());
        order.setChannelCode(financeDepositTable.getRemittanceChannelCode());
        order.setChannelName(financeDepositTable.getRemittanceChannelName());
        order.setChannelEnName(financeDepositTable.getRemittanceChannelEnName());
        goldenOrderRepository.save(order);

        List<GoldenOrderDetailsTable> details = new ArrayList<>();
        for (GoldenGoodsTable goldenGoodsTable : goodsTables) {
            GoldenOrderDetailsTable detailsTable = new GoldenOrderDetailsTable();
            BeanUtils.copyProperties(goldenGoodsTable, detailsTable);
            detailsTable.setId(null);
            detailsTable.setGoodsId(goldenGoodsTable.getId());
            detailsTable.setSerial(financeDepositTable.getSerial());
            detailsTable.setCustomId(financeDepositTable.getCustomId());

            details.add(detailsTable);

        }
        goldenOrderDetailsRepository.save(details);

        return order;
    }

    @Override
    public void save(FinanceDepositTable financeDepositTable) throws ServiceException, PayValidatedException {
        financeDepositRepository.save(financeDepositTable);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCallbackValidate(FinanceDepositCallbackValidateUpdateEntity financeDepositUpdateEntity) throws ServiceException {
        FinanceDepositTable financeDepositTable =
                financeDepositRepository.findFirstBySerial(financeDepositUpdateEntity.getSerial());

        if (financeDepositTable == null) {
            return;
        }
        financeDepositUpdateEntity.setId(financeDepositTable.getId());
        BeanUtils.copyProperties(financeDepositUpdateEntity, financeDepositTable);

        if (!PayConstants.CALLBACE_VALIDATE_SUCCESS_STATUS.equals(financeDepositTable.getCallbackValidate())) {
            financeDepositTable.setCallbackStatus(PayConstants.CALLBACE_FAIL_STATUS);
            financeDepositTable.setNote("95");
        }
        financeDepositRepository.save(financeDepositTable);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FinanceDepositTable approve(FinanceDepositApproveEntity entity) throws ServiceException {
        FinanceDepositTable financeDepositTable = financeDepositRepository.findFirstById(entity.getId());
        if (financeDepositTable == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        if (!StatusConstants.MANAGER_PENDING_STATUS.equals(financeDepositTable.getDepositStatus())
                || !StatusConstants.APPLY_STATUS.equals(financeDepositTable.getStatus())) {
            throw ServiceException.exception(Constants.CANNOT_APPROVE);
        }

        if (entity.getAmount() == null && entity.getCny() == null) {
            entity.setCny(financeDepositTable.getCny());
            entity.setAmount(financeDepositTable.getAmount());
        } else if (entity.getAmount() != null) {
            entity.setCny(entity.getAmount().multiply(financeDepositTable.getRate()));
        } else if (entity.getCny() != null) {

            BigDecimal amount = entity.getCny().divide(financeDepositTable.getRate(), 10, BigDecimal.ROUND_HALF_UP);
            entity.setAmount(amount);
        }

        BeanUtils.copyProperties(entity, financeDepositTable);

        financeDepositRepository.save(financeDepositTable);

//        if (StatusConstants.PASSED_STATUS.equals(financeDepositTable.getStatus())
//                && StatusConstants.MANAGER_COMPLETED_STATUS.equals(financeDepositTable.getDepositStatus())) {
//
//        }


        CustomInfoTable customInfoTable = customInfoRepository.findFirstById(financeDepositTable.getCustomId());
        if (customInfoTable == null) {
            throw new ServiceException(Constants.USER_NOT_EXIST_ERROR);
        }

        //调整客户是否有入金成功
        if (StatusConstants.PASSED_STATUS.equals(entity.getStatus())) {
            if (customInfoTable.getPayStatus() == null || !customInfoTable.getPayStatus().equals(1)) {
                customInfoTable.setPayStatus(1);
                customInfoRepository.save(customInfoTable);
            }
        }
        sendCustomDepositEmail(financeDepositTable, customInfoTable);
        return financeDepositTable;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(FinanceDepositDeleteEntity entity) throws ServiceException {
        List<FinanceDepositTable> allByIdIn = financeDepositRepository.findAllByIdIn(entity.getIds());
        if (allByIdIn == null || allByIdIn.size() <= 0) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }

        financeDepositRepository.delete(allByIdIn);
    }

    @Override
    public ResultWithPagerDto<FinanceDepositDto> searchPageList(FinanceDepositSearchListEntity entity) throws ServiceException {
        Integer count = financeDepositMapper.countList(entity);
        PageDto pageDto = PageDto.format(entity, count);
        if (count == null || count <= 0) {
            return ResultWithPagerDto.success(pageDto);
        }

        BaseResultDto<List<FinanceDepositDto>> listBaseResultDto = searchList(entity);

        return ResultWithPagerDto.success(pageDto, listBaseResultDto.getData());
    }

    @Override
    public BaseResultDto<List<FinanceDepositDto>> searchList(FinanceDepositSearchListEntity entity) throws ServiceException {

        List<FinanceDepositView> financeDepositViews = financeDepositMapper.searchList(entity);

        if (financeDepositViews == null || financeDepositViews.size() <= 0) {

            throw new ServiceException(Constants.SYSTEM_ERROR);
        }
        List<FinanceDepositDto> financeDepositDtos = new ArrayList<>(financeDepositViews.size());

        for (FinanceDepositView financeDepositView : financeDepositViews) {
            FinanceDepositDto transform = transform(financeDepositView);
            financeDepositDtos.add(transform);
        }

        return BaseResultDto.success(financeDepositDtos);
    }

    @Override
    public FinanceDepositDto searchSingle(Long id) throws ServiceException {
        FinanceDepositView financeDepositMapperSingle = financeDepositMapper.getOne(id);
        if (financeDepositMapperSingle == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        return transform(financeDepositMapperSingle);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public void updateCallback(FinanceDepositCallbackUpdateEntity financeDepositCallbackUpdateEntity) throws ServiceException {
        String lockKey = "FINANCE_DEPOSIT:";
        if (!Strings.isNullOrEmpty(financeDepositCallbackUpdateEntity.getSerial())) {
            lockKey = lockKey + financeDepositCallbackUpdateEntity.getSerial();
        } else if (!Strings.isNullOrEmpty(financeDepositCallbackUpdateEntity.getTicket())) {
            lockKey = lockKey + financeDepositCallbackUpdateEntity.getTicket();
        } else {
            throw ServiceException.exception(Constants.SYSTEM_ERROR);
        }
        String co = UUIDUtil.getUUID();
        try {
            if (redisService.tryLock(lockKey, co, 60 * 1000)) {
                //获取订单
                FinanceDepositTable financeDepositTable = null;
                if (!Strings.isNullOrEmpty(financeDepositCallbackUpdateEntity.getSerial())) {
                    financeDepositTable =
                            financeDepositRepository.findFirstBySerial(financeDepositCallbackUpdateEntity.getSerial());
                } else if (!Strings.isNullOrEmpty(financeDepositCallbackUpdateEntity.getTicket())) {
                    financeDepositTable =
                            financeDepositRepository.findFirstByChannelSerial(financeDepositCallbackUpdateEntity.getTicket());
                } else {
                    throw ServiceException.exception(Constants.SYSTEM_ERROR);
                }
                if (financeDepositTable == null) {
                    throw new ServiceException(Constants.SYSTEM_ERROR);
                }

                CustomInfoTable customTable = customInfoRepository.findFirstById(financeDepositTable.getCustomId());
                if (customTable == null) {
                    throw new ServiceException(Constants.SYSTEM_ERROR);
                }

                GoldenOrderTable orderTable = goldenOrderRepository.findFirstBySerial(financeDepositCallbackUpdateEntity.getSerial());
                if (orderTable == null) {
                    throw new ServiceException(Constants.SYSTEM_ERROR);
                }

                if (!isIpWhitelist(financeDepositTable.getRemittanceChannelCode())) {

                    throw ServiceException.exception("ip error");
                }
                if (PayConstants.CALLBACE_SUCCESS_STATUS.equals(financeDepositTable.getCallbackStatus())) {
                    return;
                }

                //填充订单数据
                if (!Strings.isNullOrEmpty(financeDepositCallbackUpdateEntity.getChannelSerial())) {
                    financeDepositTable.setChannelSerial(financeDepositCallbackUpdateEntity.getChannelSerial());
                }
                financeDepositTable.setStatus(financeDepositCallbackUpdateEntity.getStatus());
                financeDepositTable.setCallbackStatus(financeDepositCallbackUpdateEntity.getCallbackStatus());
                financeDepositTable.setModifyTime(new Date());
                financeDepositTable.setCallbackTime(financeDepositCallbackUpdateEntity.getCallbackTime() == null ?
                        new Date() : financeDepositCallbackUpdateEntity.getCallbackTime());
                financeDepositTable.setNote(financeDepositCallbackUpdateEntity.getNote());
                if (financeDepositCallbackUpdateEntity.getRate() != null) {
                    financeDepositTable.setRate(financeDepositCallbackUpdateEntity.getRate());
                }
                //根据回调实体中是否有金额判断回调订单金额可能存在变动 并再次进行计算填充
                if (financeDepositCallbackUpdateEntity.getAmount() != null) {
                    financeDepositTable.setAmount(financeDepositCallbackUpdateEntity.getAmount());
                    if (financeDepositCallbackUpdateEntity.getTransformAmount() != null) {
                        financeDepositTable.setTransformAmount(financeDepositCallbackUpdateEntity.getTransformAmount());
                    } else {
                        BigDecimal rate = financeDepositTable.getRate();
                        BigDecimal transformAmount = financeDepositCallbackUpdateEntity.getAmount().multiply(rate);
                        financeDepositTable.setTransformAmount(transformAmount);
                    }
                } else if (financeDepositCallbackUpdateEntity.getTransformAmount() != null) {
                    if (financeDepositCallbackUpdateEntity.getTransformAmount().compareTo(financeDepositTable.getTransformAmount()) != 0) {

                        financeDepositTable.setTransformAmount(financeDepositCallbackUpdateEntity.getTransformAmount());
                        BigDecimal rate = financeDepositTable.getRate();
                        BigDecimal amount = financeDepositTable.getTransformAmount().divide(rate, 10,
                                BigDecimal.ROUND_HALF_UP);
                        financeDepositTable.setAmount(amount);
                    } else {
                        financeDepositCallbackUpdateEntity.setTransformAmount(null);
                    }
                }

                if (financeDepositCallbackUpdateEntity.getAmount() != null || financeDepositCallbackUpdateEntity.getTransformAmount() != null) {
                    BigDecimal depositAmount = getDepositAmount(financeDepositTable);
                    Integer free = financeDepositTable.getFree();
                    if (free != null && free.compareTo(0) > 0) {
                        depositAmount = depositAmount.multiply(new BigDecimal(1 - (free / 100.0)));
                    }
                    financeDepositTable.setDepositAmount(depositAmount);
                    BigDecimal cnyAmount = getCnyAmount(financeDepositTable);
                    financeDepositTable.setCny(cnyAmount);
                }
                //保存回调数据
                financeDepositTable.setCallbackData(financeDepositCallbackUpdateEntity.getCallbackData());
                financeDepositTable.setModifyIp(getIp());
                if (StringUtils.isNotEmpty(financeDepositCallbackUpdateEntity.getApproveDesc())) {
                    financeDepositTable.setApproveDesc(financeDepositCallbackUpdateEntity.getApproveDesc());
                    financeDepositTable.setOperationType(PayConstants.OPERATION_TYPE_AUTOMATIC);
                    financeDepositTable.setApproveTime(new Date());
                }
                //更新订单
                financeDepositRepository.save(financeDepositTable);

                //成功处理
                if (PayConstants.CALLBACE_SUCCESS_STATUS.equals(financeDepositTable.getCallbackStatus())) {
                    BigDecimal totalSpendingAmount = customTable.getTotalSpendingAmount() == null ? BigDecimal.ZERO : customTable.getTotalSpendingAmount();
                    customTable.setTotalSpendingAmount(totalSpendingAmount.add(financeDepositTable.getAmount()));

                    customInfoRepository.save(customTable);

                    orderTable.setStatus(PayConstants.ORDER_PAY_STATUS);
                    orderTable.setPayTime(financeDepositTable.getCallbackTime());
                } else if (PayConstants.CALLBACE_FAIL_STATUS.equals(financeDepositTable.getCallbackStatus())) {
                    orderTable.setStatus(PayConstants.ORDER_PAY_ERROR_STATUS);
                }
                orderTable.setModifyTime(new Date());
                goldenOrderRepository.save(orderTable);

                if (customTable.getTotalSpendingAmount().compareTo(new BigDecimal(5000)) >= 0) {
                    mqSendService.send(ConfigConstants.CUSTOM_REWARD_RECORD, customTable.getId());
                }

                if (PayConstants.CALLBACE_SUCCESS_STATUS.equals(financeDepositTable.getCallbackStatus())) {
                    List<GoldenOrderDetailsTable> detailsTables =  goldenOrderDetailsRepository.getBySerial(financeDepositTable.getSerial());
                    for (GoldenOrderDetailsTable detailsTable : detailsTables) {
                        sendCustomGoldenOrderEmail(orderTable.getPayName(),detailsTable.getDownload(),customTable.getEmail());
                    }

                }

            }

        } catch (Exception e) {
            log.error(e.getMessage());
            throw ServiceException.exception(Constants.SYSTEM_ERROR);
        } finally {
            redisService.unlock(lockKey, co);
        }
    }

    @Override
    public boolean isIpWhitelist(String channelCode) throws ServiceException {

        SysRemittanceChannelTable payChannel = sysRemittanceChannelRepository.getFirstByCode(channelCode);
        if (payChannel == null) {
            throw new ServiceException(Constants.SYSTEM_ERROR);
        }
        if (Strings.isNullOrEmpty(payChannel.getWhitelist())) {
            return true;
        }
        String ip = getIp();
        if (Strings.isNullOrEmpty(ip)) {
            return false;
        }

        log.info(String.format("pay callback,Whitelist error,Whitelist :%s,ip:%s", payChannel.getWhitelist(), ip));
        if (Arrays.asList(payChannel.getWhitelist().split(",")).contains(ip)) {
            return true;
        }

        log.info(String.format("pay callback,Whitelist error"));
        return false;
    }

    /**
     * 获取通道银行信息
     *
     * @param balanceSaveEntity
     * @param channel
     * @return
     * @throws ServiceException
     */
    @Override
    public SysChannelBankTable getChannelBank(FinanceDepositAddEntity balanceSaveEntity,
                                              SysRemittanceChannelTable channel)
            throws ServiceException {
        SysChannelBankTable sysChannelBankTable = null;
        if (channel.getBankValid() != null && channel.getBankValid().equals(1)) {
            if (!Strings.isNullOrEmpty(balanceSaveEntity.getBankCode())) {
                sysChannelBankTable = sysChannelBankService.getByCode(balanceSaveEntity.getBankCode(),
                        channel.getCode());
                if (sysChannelBankTable == null) {
                    throw new ServiceException(Constants.SYSTEM_ERROR);
                }
                balanceSaveEntity.setTransformCurrency(sysChannelBankTable.getCurrency());
            } else {
                throw new ServiceException(Constants.SYSTEM_ERROR);
            }
        }
        return sysChannelBankTable;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FinanceDepositTable getBySerial(String serial) throws ServiceException {
        FinanceDepositTable financeDepositTable = financeDepositRepository.getFirstBySerial(serial);
        if (financeDepositTable == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        return financeDepositTable;
    }

    @Override
    public FinanceDepositTable getByChannelSerial(String channelSerial) throws ServiceException {
        FinanceDepositTable financeDepositTable = financeDepositRepository.getFirstByChannelSerial(channelSerial);
        return financeDepositTable;
    }


    /**
     * 过期时间修改状态
     * @param content
     * @throws ServiceException
     */
    @JmsListener(destination = PayConstants.ORDER_DEPOSIT_EXPIRE)
    @Transactional(rollbackFor = Exception.class)
    public void orderDepositExpire(String content) throws ServiceException {
        log.info(String.format("ORDER_DEPOSIT_EXPIRE,content:%s", content));

        GoldenOrderTable order = JSON.parseObject(content, GoldenOrderTable.class);
        if (order == null) {
            log.error("ORDER_DEPOSIT_EXPIRE,entity is null");
            return;
        }

        GoldenOrderTable table = goldenOrderRepository.findFirstBySerial(order.getSerial());
        if (table == null) {
            return;
        }

        if (table.getStatus() == PayConstants.ORDER_UP_PAY_STATUS) {
            table.setStatus(PayConstants.ORDER_PAY_EXPIRED_STATUS);
            table.setModifyTime(new Date());
            goldenOrderRepository.save(table);
        }

    }


    private FinanceDepositDto transform(FinanceDepositView financeDepositView) {
        FinanceDepositDto financeDepositDto = new FinanceDepositDto();
        BeanUtils.copyProperties(financeDepositView, financeDepositDto);
        return financeDepositDto;
    }

    private void sendDepositEmail(FinanceDepositTable table) throws ServiceException {

        SysConfigTable sysConfigTable = sysConfigService.getByCode(ConfigConstants.FINANCE_DEPOSIT_MANAGER_EMAIL);
        if (sysConfigTable == null) {
            throw new ServiceException(Constants.SYSTEM_ERROR);
        }
        String users = sysConfigTable.getValue();

        if (users == null) {
            throw new ServiceException(Constants.SYSTEM_ERROR);
        }
        //构建map 用于后面邮件模版替换
        Map<String, String> map = new HashMap<>(10);

        map.put(MapConstants.LOGIN, table.getLogin() + "");

        map.put(MapConstants.NAME, table.getName());

        map.put(MapConstants.DEPOSIT_AMOUNT, table.getAmount() == null ? "" : String.format("%.2f",
                table.getAmount().doubleValue()));
        map.put(MapConstants.APPLY_TIME, DateUtil.formatTime(table.getAddTime()));
        map.put(MapConstants.SERIAL, table.getSerial());
        map.put(MapConstants.DATE_TIME, DateUtil.formatTime(new Date()));

        SysEmailSendEntity sysEmailSendEntity = new SysEmailSendEntity();
        sysEmailSendEntity.setSubject("CWG DEPOSIT");
        sysEmailSendEntity.setEmailSendEnum(EmailSendEnum.FINANCE_DEPOSIT_NOTICE);
        sysEmailSendEntity.setMap(map);
        sysEmailSendEntity.setTemplateName(EmailTemplateConstants.FINANCE_DEPOSIT_NOTICE_NAME);
        sysEmailSendEntity.setUsers(users);
        try {
            emailService.sendEmail(sysEmailSendEntity);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void sendCustomDepositEmail(FinanceDepositTable table, CustomInfoTable customInfoTable) throws ServiceException {


        //构建map 用于后面邮件模版替换
        Map<String, String> map = new HashMap<>(10);
        String name = CustomInfoUtil.getName(customInfoTable);

        map.put(MapConstants.NAME, name);
        map.put(MapConstants.LOGIN, String.valueOf(table.getLogin()));

        map.put(MapConstants.DEPOSIT_AMOUNT, table.getAmount() == null ? "" : String.format("%.2f",
                table.getAmount().doubleValue()));
        map.put(MapConstants.DATE_TIME, DateUtil.formatTime(new Date()));
        map.put(MapConstants.APPROVE_DESC, table.getApproveDesc());
        map.put(MapConstants.APPROVE_STATUS, table.getStatus().equals(2) ? "通过" : "拒绝");

        SysEmailSendEntity sysEmailSendEntity = new SysEmailSendEntity();
        sysEmailSendEntity.setSubject("CWG DEPOSIT");
        sysEmailSendEntity.setEmailSendEnum(EmailSendEnum.CUSTOM_FINANCE_DEPOSIT_NOTICE);
        sysEmailSendEntity.setMap(map);

        sysEmailSendEntity.setTemplateName(EmailTemplateConstants.FINANCE_DEPOSIT_APPROVE_NOTICE_RESULT);

        sysEmailSendEntity.setUsers(customInfoTable.getEmail());
        try {
            emailService.sendEmail(sysEmailSendEntity);
            WebNoticeRecordAndEmailMqEntity mqEntity = new WebNoticeRecordAndEmailMqEntity(sysEmailSendEntity,
                    table.getCId(), table.getCustomId());
            mqSendService.send(Constants.WEB_NOTICE_PUT_RECORD, mqEntity);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void sendCustomGoldenOrderEmail(String name, String download,String email) throws ServiceException {

        //构建map 用于后面邮件模版替换
        Map<String, String> map = new HashMap<>(3);

        map.put(MapConstants.NAME, name);

        map.put(ConfigConstants.DOWNLOAD_URL, download);
        map.put(MapConstants.DATE_TIME, DateUtil.formatTime(new Date()));

        SysEmailSendEntity sysEmailSendEntity = new SysEmailSendEntity();
        sysEmailSendEntity.setSubject("Trading Education");
        sysEmailSendEntity.setEmailSendEnum(EmailSendEnum.CUSTOM_ORDER_SUCCESS);
        sysEmailSendEntity.setMap(map);
        sysEmailSendEntity.setTemplateName(EmailTemplateConstants.CUSTOM_ORDER_SUCCESS_CN);


        sysEmailSendEntity.setUsers(email);
        try {
            emailService.sendEmail(sysEmailSendEntity);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }



    private SysConfigFinanceEntity getConfigFinance() throws ServiceException {

        SysConfigTable sysConfigTable = sysConfigService.getByCode(ConfigConstants.FINANCE_CONFIGURE);
        SysConfigFinanceEntity financeEntity = JSON.parseObject(sysConfigTable.getValue(),
                SysConfigFinanceEntity.class);
        if (financeEntity == null) {
            throw ServiceException.exception(Constants.SYSTEM_ERROR);
        }
        return financeEntity;
    }

    /**
     * 验证最大和最小入金量
     *
     * @param balanceSaveEntity
     * @throws ServiceException
     */
    private void validatedAmount(FinanceDepositAddEntity balanceSaveEntity, SysRemittanceChannelTable channel,
                                 SysChannelBankTable sysChannelBankTable) throws ServiceException,
            PayValidatedException {
        BigDecimal max = null;
        BigDecimal min = null;
        List<String> excludeCodes = null;

        List<String> codes = new ArrayList<>(2);

        //获取自动时段最大入金量
        SysConfigTable sysConfigTable = sysConfigService.getByCode(ConfigConstants.AUTOLIMIT_DEPOSIT_CONFIG);
        SysConfigAutolimitEntity sysConfigAutolimitEntity = JSON.parseObject(sysConfigTable.getValue(),
                SysConfigAutolimitEntity.class);
        if (sysConfigAutolimitEntity == null) {
            throw ServiceException.exception(Constants.SYSTEM_ERROR);
        }
        if (sysConfigAutolimitEntity.getAutolimitVaild() != null && sysConfigAutolimitEntity.getAutolimitVaild().equals(1)) {
            //特定通道排除在外
            if (!Strings.isNullOrEmpty(sysConfigAutolimitEntity.getExcludeCodes())) {
                excludeCodes = Arrays.asList(sysConfigAutolimitEntity.getExcludeCodes().split(","));
            }
            //验证时间在那个区间
            if (excludeCodes == null || !excludeCodes.contains(balanceSaveEntity.getPayType())) {
                Date newDate = new Date();
                Time newTime =
                        Time.valueOf(newDate.getHours() + ":" + newDate.getMinutes() + ":" + newDate.getSeconds());
                if (newTime.getTime() > sysConfigAutolimitEntity.getStartTime().getTime()
                        && newTime.getTime() < sysConfigAutolimitEntity.getEndTime().getTime()) {
                    max = sysConfigAutolimitEntity.getWithinIntervalAmount();
                } else {
                    max = sysConfigAutolimitEntity.getOutRangeAmount();
                }
            }
        }

        //判断银行(货币)通道上是否携带最大最小入金量
        if (sysChannelBankTable != null) {
            if (sysChannelBankTable.getMinAmount() != null) {
                min = sysChannelBankTable.getMinAmount();
            }
            if (sysChannelBankTable.getMaxAmount() != null) {
                max = sysChannelBankTable.getMaxAmount();
            }
        }
        //判断通道上是否携带最大入金量
        if (max == null) {
            if (channel.getMaxAmount() == null) {
                codes.add(ConfigConstants.FINANCE_DEPOSIT_MAX);
            } else {
                max = channel.getMaxAmount();
            }
        }

        //判断通道上是否携带最小入金量
        if (min == null) {
            if (channel.getMinAmount() == null) {
                codes.add(ConfigConstants.FINANCE_DEPOSIT_MIN);
            } else {
                min = channel.getMinAmount();
            }
        }
        //如果最大最小入金量都没设置 则使用全局设置的最大最小入金量
        if (codes.size() > 0) {
            List<SysConfigTable> configTables = sysConfigService.getByCodes(codes);
            if (configTables == null || configTables.size() < codes.size()) {
                throw new ServiceException(Constants.SYSTEM_ERROR);
            }
            for (SysConfigTable configTable : configTables) {

                if (ConfigConstants.FINANCE_DEPOSIT_MAX.equals(configTable.getCode())) {
                    try {
                        max = new BigDecimal(configTable.getValue());
                    } catch (NumberFormatException e) {
                        throw new ServiceException(Constants.SYSTEM_ERROR);
                    }
                }
                if (ConfigConstants.FINANCE_DEPOSIT_MIN.equals(configTable.getCode())) {
                    try {
                        min = new BigDecimal(configTable.getValue());
                    } catch (NumberFormatException e) {
                        throw new ServiceException(Constants.SYSTEM_ERROR);
                    }
                }
            }
        }

        if (balanceSaveEntity.getAmount().intValue() < min.intValue()) {
            throw new PayValidatedException(localeMessage.getMessage(PayConstants.FINANCE_DEPOSIT_AMOUNT_LESS_THAN,
                    PayConstants.FINANCE_DEPOSIT_AMOUNT_LESS_THAN) + min.intValue() + " " + channel.getCurrency());
        }
        if (balanceSaveEntity.getAmount().intValue() > max.intValue()) {
            throw new PayValidatedException(localeMessage.getMessage(PayConstants.FINANCE_DEPOSIT_AMOUNT_GREATER_THAN,
                    PayConstants.FINANCE_DEPOSIT_AMOUNT_GREATER_THAN) + max.intValue() + " " + channel.getCurrency());
        }
    }

    private void validatedAmount(FinanceDepositAddEntity balanceSaveEntity, SysConfigFinanceEntity financeEntity) throws ServiceException, PayValidatedException {
        if (balanceSaveEntity.getAmount().intValue() < financeEntity.getMinDeposit().intValue()) {
            throw new PayValidatedException(localeMessage.getMessage(PayConstants.FINANCE_DEPOSIT_AMOUNT_LESS_THAN,
                    PayConstants.FINANCE_DEPOSIT_AMOUNT_LESS_THAN) + financeEntity.getMinDeposit().intValue());
        }
        if (balanceSaveEntity.getAmount().intValue() > financeEntity.getMaxDeposit().intValue()) {
            throw new PayValidatedException(localeMessage.getMessage(PayConstants.FINANCE_DEPOSIT_AMOUNT_GREATER_THAN
                    , PayConstants.FINANCE_DEPOSIT_AMOUNT_GREATER_THAN) + financeEntity.getMaxDeposit().intValue());
        }
    }

    /**
     * 获取交易账户
     *
     * @param balanceSaveEntity
     * @return
     * @throws ServiceException
     */
    private CustomLoginTable getCustomLogin(FinanceDepositAddEntity balanceSaveEntity) throws ServiceException {
        CustomLoginTable customLoginTable = customLoginService.getByCustomIdAndLogin(balanceSaveEntity.getCustomId(),
                balanceSaveEntity.getLogin());
        if (customLoginTable == null) {
            throw ServiceException.exception(Constants.NOT_PERMIT);
        }
        return customLoginTable;
    }

    /**
     * 获取客户信息
     *
     * @param balanceSaveEntity
     * @return
     * @throws ServiceException
     */
    private CustomInfoTable getCustomInfo(FinanceDepositAddEntity balanceSaveEntity) throws ServiceException {
        CustomInfoTable customInfoTable = customInfoRepository.getFirstById(balanceSaveEntity.getCustomId());
        if (customInfoTable == null) {
            throw new ServiceException(Constants.USER_NOT_EXIST_ERROR);
        }

        return customInfoTable;
    }

    /**
     * 获取实际通道使用金额
     *
     * @param balanceSaveEntity
     * @return
     * @throws ServiceException
     */
    private BigDecimal getTransformAmount(FinanceDepositAddEntity balanceSaveEntity,
                                          SysRemittanceChannelTable channel) throws ServiceException {

        //获取汇率 如果特定通道没有汇率 则根据我方设定汇率计算
        BigDecimal rate;
        if (balanceSaveEntity.getRate() == null) {

            if (channel.getRate() == null) {
                if (balanceSaveEntity.getCurrency().equals(balanceSaveEntity.getTransformCurrency())) {
                    rate = BigDecimal.ONE;
                } else {
                    rate = financeRateService.getRate(balanceSaveEntity.getCurrency(),
                            balanceSaveEntity.getTransformCurrency(), 0, 1);
                }
            } else {
                rate = channel.getRate();
            }
            balanceSaveEntity.setRate(rate);
        }

        BigDecimal transformAmount = null;
        if (balanceSaveEntity.getTransformAmount() != null) {
            transformAmount = balanceSaveEntity.getTransformAmount();
            BigDecimal amount = transformAmount.divide(balanceSaveEntity.getRate(), 2, BigDecimal.ROUND_DOWN);
            balanceSaveEntity.setAmount(amount);
        } else {
            transformAmount = balanceSaveEntity.getAmount().multiply(balanceSaveEntity.getRate());

        }
        return transformAmount;
    }

    /**
     * 获取手续费
     *
     * @param channel
     * @param sysChannelBankTable
     * @return
     */
    private Integer getFree(SysRemittanceChannelTable channel, SysChannelBankTable sysChannelBankTable) {
        Integer free = null;
        //判断如果银行(支付货币)类型关闭且通道汇率不为空 且通道汇率大于0 或者银行(支付货币)开启且银行(支付货币)汇率不为空 且银行(支付货币)汇率大于0
        if ((channel.getBankValid() == null || channel.getBankValid().compareTo(0) == 0)
                && channel.getFree() != null
                && channel.getFree().compareTo(0) > 0) {
            free = channel.getFree();
        }
        if ((channel.getBankValid() != null && channel.getBankValid().compareTo(0) > 0)
                && sysChannelBankTable != null && sysChannelBankTable.getFree() != null
                && sysChannelBankTable.getFree().compareTo(0) > 0) {
            free = sysChannelBankTable.getFree();
        }
        return free;
    }

    private void setFinanceDepositAddRate(FinanceDepositAddEntity balanceSaveEntity,
                                          SysRemittanceChannelTable channel,
                                          SysChannelBankTable sysChannelBankTable) {
        if (balanceSaveEntity.getRate() != null) {
            return;
        }

        if (sysChannelBankTable != null && sysChannelBankTable.getRate() != null) {
            balanceSaveEntity.setRate(sysChannelBankTable.getRate());
            return;
        }

        if (channel != null && channel.getRate() != null) {
            balanceSaveEntity.setRate(channel.getRate());
            return;
        }
    }

    /**
     * 获取平台入金金额
     *
     * @param financeDepositTable
     * @return
     * @throws ServiceException
     */
    private BigDecimal getDepositAmount(FinanceDepositTable financeDepositTable) throws ServiceException {
        BigDecimal depositAmount = null;
        if (financeDepositTable.getDepositCurrency().equals(financeDepositTable.getCurrency())) {
            depositAmount = financeDepositTable.getAmount();
        } else {
            //获取汇率 如果特定通道没有汇率 则根据我方设定汇率计算
            BigDecimal rate = financeRateService.getRate(financeDepositTable.getCurrency(),
                    financeDepositTable.getDepositCurrency(), 0, 1);

            if (rate == null) {
                log.error(String.format("currency:%s,depositCurrency:%s,type:%d", financeDepositTable.getCurrency(),
                        financeDepositTable.getDepositCurrency(), 0));
                throw ServiceException.exception();
            }
            depositAmount = financeDepositTable.getAmount().multiply(rate);
        }
        return depositAmount;
    }

    /**
     * 获取cny金额
     *
     * @param financeDepositTable
     * @return
     * @throws ServiceException
     */
    private BigDecimal getCnyAmount(FinanceDepositTable financeDepositTable) throws ServiceException {
        BigDecimal cnyAmount = null;
        if ("CNY".equals(financeDepositTable.getTransformCurrency().toUpperCase())) {
            return financeDepositTable.getTransformAmount();
        }
        BigDecimal cnyRate = financeRateService.getRate(financeDepositTable.getCurrency(), "CNY", 0, 1);
        if (cnyRate != null) {
            cnyAmount = financeDepositTable.getAmount().multiply(cnyRate);
        }
        return cnyAmount;
    }

    private BigDecimal getCnyAmount(FinanceDepositAddEntity balanceSaveEntity) throws ServiceException {
        BigDecimal cnyAmount = null;
        BigDecimal cnyRate = financeRateService.getRate(balanceSaveEntity.getCurrency(), "CNY", 0, 1);
        if (cnyRate != null) {
            cnyAmount = balanceSaveEntity.getAmount().multiply(cnyRate);
        }
        return cnyAmount;
    }

    protected String getIp() throws ServiceException {

        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (requestAttributes == null) {
            return null;
        }
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        if (request == null) {
            return null;
        }
        String ip = GetIpAndMac.getIp(request);
        return ip;
    }

    /**
     * 生成订单号
     *
     * @return 订单号
     */
    private String getOrderNo() {
        /**
         * 生成订单号
         */
        String orderNo = GetRandom.getOrderNo(PayConstants.DEPOSIT_HEAD);
        return orderNo;
    }



}
