package com.neusoft.smart.pos.payment.service;

import com.alibaba.fastjson.JSON;
import com.neusoft.smart.pos.constants.DictionaryConstant;
import com.neusoft.smart.pos.dto.payment.request.*;
import com.neusoft.smart.pos.dto.payment.response.*;
import com.neusoft.smart.pos.framework.exception.BusinessCommonException;
import com.neusoft.smart.pos.framework.utils.*;
import com.neusoft.smart.pos.payment.constants.PaymentConstants;
import com.neusoft.smart.pos.payment.constants.PaymentErrorCode;
import com.neusoft.smart.pos.payment.persistent.domain.GrantPayOrder;
import com.neusoft.smart.pos.payment.repository.*;
import com.neusoft.smart.pos.payment.utils.LogUtils;
import lombok.val;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;


@Service("grantPayService")
public class GrantPayService {

    private final static Logger logger = LoggerFactory.getLogger(GrantPayService.class);

	@Autowired
    private MchPayChannelRepository mchPayChannelRepository;

    @Autowired
    private GrantPayOrderRepository grantPayOrderRepository;

    @Autowired
    private PayTypeDictRepository payTypeDictRepository;

    @Autowired
    private MchPayInfoRepository mchPayInfoRepository;

    /**
     * 第三方支付单生成方法
     * @return
     */
    public PostFreePayResponse freezePay(PostFreePayRequest freePayRequest) {
        //1.根据商户号查询商户信息
        val mchPayInfo = mchPayInfoRepository.queryMchPayInfoByMcode(freePayRequest.getMcode(),DictionaryConstant.PAYMENT_MCH_STATUS_SHTG.getCode());
        if(null == mchPayInfo){
            throw new BusinessCommonException(PaymentErrorCode.MCH_INFO_NOT_EXIST);
        }

        //2.校验签名信息
        if(!SignUtils.isSignatureValid(MapBeanUtils.beanToMap(freePayRequest),mchPayInfo.getSecretKey())){
            throw new BusinessCommonException(PaymentErrorCode.SIGN_VALID_ERROR);
        }

        //3.校验订单失效时间是否合法，订单失效时间至少与当前时间间隔5分钟,如何为空则默认设置为2小时
        if(StringUtils.isEmpty(freePayRequest.getTimeExpire())){
            String localDateTime = LocalDateTimeUtils.convertLocalDateTimeToString(LocalDateTimeUtils.plusMinutes(LocalDateTimeUtils.getNow(), PaymentConstants.DEFAULT_TIME_EXPIRE),LocalDateTimeUtils.SIMPLE_DATETIME_FORMAT);
            freePayRequest.setTimeExpire(localDateTime);
        }else{
            val betweenMinutes = LocalDateTimeUtils.betweenNowMinutes(LocalDateTimeUtils.convertStringToLocalDateTime(freePayRequest.getTimeExpire(),LocalDateTimeUtils.SIMPLE_DATETIME_FORMAT));
            if(betweenMinutes < 5){
                throw new BusinessCommonException(PaymentErrorCode.MCH_ORDER_TIME_EXPIRE_TOO_SHORT);
            }
        }

        //4.整理支付平台预付单信息
        val tradeId = IdGenerateUtils.generateTradeId();    //当前时间毫秒数+5位随机数
        val grantPayOrder = grantPayOrderDataHandle(tradeId,freePayRequest);

        //5.校验支付成功回调url
        val mchPayChannel = mchPayChannelRepository.queryMchPayChannelByMcodeWithBlob(grantPayOrder.getMcode(),grantPayOrder.getPayType());
        if(null == mchPayChannel){
            throw new BusinessCommonException(PaymentErrorCode.MCH_THIRD_PLATFORM_NOT_CONFIG);
        }

        //6.生成第三方支付平台预付单信息
        if(StringUtils.isEmpty(mchPayChannel.getNotifyUrl()) && StringUtils.isEmpty(grantPayOrder.getNotifyUrl())){
            throw new BusinessCommonException(PaymentErrorCode.MCH_NOTIFY_URL_EMPTY);
        }else if(StringUtils.isEmpty(grantPayOrder.getNotifyUrl())){
            grantPayOrder.setNotifyUrl(mchPayChannel.getNotifyUrl());
        }
        val payTypeDict = payTypeDictRepository.queryEnablePayTypeDict(grantPayOrder.getPayType());
        //根据BeanName获取spring实现类
        val thirdPayRepository = SpringUtils.getBean(payTypeDict.getBeanName(),IThirdPayGrantRepository.class);
        val thirdPlatformOrder = thirdPayRepository.freezePayToThirdPlatform(grantPayOrder,mchPayChannel,payTypeDict);

        //7.根据第三方平台预付单信息更新支付平台预付单信息
        grantPayOrder.setOuterOrderNumber(thirdPlatformOrder.getOuterOrderNumber());
        grantPayOrder.setCodeUrl(thirdPlatformOrder.getOuterCodeUrl());
        grantPayOrder.setGrantStatus(thirdPlatformOrder.getPayFreezeStatus());
        grantPayOrderRepository.createGrantPayOrder(grantPayOrder);

        //8.整理返回数据并记录相关日志，异常信息可不记录日志，在日志文件中可查看
        val freePayResponse = new PostFreePayResponse();
        freePayResponse.setMcode(thirdPlatformOrder.getMcode());
        freePayResponse.setPayCode(thirdPlatformOrder.getOuterCodeUrl());
        freePayResponse.setAuthNo(thirdPlatformOrder.getAuthNo());
        freePayResponse.setGrantStatus(thirdPlatformOrder.getPayFreezeStatus());
        freePayResponse.setGrantTime(thirdPlatformOrder.getGrantTime());
        freePayResponse.setOrderNumber(thirdPlatformOrder.getMOrderNumber());
        freePayResponse.setOuterOrderNumber(thirdPlatformOrder.getOuterOrderNumber());
        freePayResponse.setPayType(freePayRequest.getPayType());
        freePayResponse.setTimeExpire(freePayRequest.getTimeExpire());
        freePayResponse.setTradeId(tradeId);
        val sign = SignUtils.generateSign(MapBeanUtils.beanToMap(freePayResponse),mchPayInfo.getSecretKey());
        freePayResponse.setSign(sign);
        LogUtils.saveMchPaymentTradeLog(thirdPlatformOrder.getMcode(),thirdPlatformOrder.getMOrderNumber(),grantPayOrder.getPayType(),LogUtils.LOG_DESCRIPTION_DDSC,JSON.toJSONString(freePayResponse), JSON.toJSONString(freePayRequest),DictionaryConstant.PAYMENT_REQUEST_TYPE_BD.getCode());
        return freePayResponse;
    }

    /**
     * 生成聚合平台预付单信息
     * @param tradeId
     * @param freePayRequest
     */
    private GrantPayOrder grantPayOrderDataHandle(String tradeId, PostFreePayRequest freePayRequest){
        //1.查询业务订单是否已经生成
        val payOrderTemp = grantPayOrderRepository.queryGrantPayOrder(freePayRequest.getMcode(),freePayRequest.getOrderNumber(),freePayRequest.getPayType());
        if(null != payOrderTemp){
            throw new BusinessCommonException(PaymentErrorCode.MCH_ORDER_REPEAT);
        }
        //2.整理订单数据
        val grantPayOrder = new GrantPayOrder();
        BeanUtils.copyProperties(freePayRequest,grantPayOrder);
        grantPayOrder.setmOrderNumber(freePayRequest.getOrderNumber());
        grantPayOrder.setTradeId(tradeId);
        grantPayOrder.setGrantAmount(freePayRequest.getOrderAmount());
        grantPayOrder.setPayIp(freePayRequest.getIp());
        return grantPayOrder;
    }

//    /**
//     * 订单信息查询使用方法
//     * @param queryOrderRequest
//     * @return
//     */
//    public PostQueryOrderResponse queryOrder(PostQueryOrderRequest queryOrderRequest){
//        //1.查询商户号信息
//        val mchPayInfo = mchPayInfoRepository.queryMchPayInfoByMcode(queryOrderRequest.getMcode(),DictionaryConstant.PAYMENT_MCH_STATUS_SHTG.getCode());
//        if(null == mchPayInfo){
//            throw new BusinessCommonException(PaymentErrorCode.MCH_INFO_NOT_EXIST);
//        }
//
//        //2.校验签名信息
//        if(!SignUtils.isSignatureValid(MapBeanUtils.beanToMap(queryOrderRequest),mchPayInfo.getSecretKey())){
//            throw new BusinessCommonException(PaymentErrorCode.SIGN_VALID_ERROR);
//        }
//        //3.查询聚合支付平台预付单信息
//        val payOrder = payOrderRepository.queryPayOrder(queryOrderRequest.getMcode(),queryOrderRequest.getOrderNumber(),queryOrderRequest.getPayType());
//
//        //4.查询第三方支付平台预付单信息
//        val mchPayChannel = mchPayChannelRepository.queryMchPayChannelByMcodeWithBlob(queryOrderRequest.getMcode(),queryOrderRequest.getPayType());
//        val payTypeDict = payTypeDictRepository.queryEnablePayTypeDict(queryOrderRequest.getPayType());
//        val thirdPayRepository = SpringUtils.getBean(payTypeDict.getBeanName(),IThirdPayRepository.class);
//        val thirdPlatformQueryOrder = thirdPayRepository.queryPayOrderFromThirdPlatform(payOrder,mchPayChannel);
//
//
//        //5.判断订单状态是否有变化,更新聚合平台订单状态
//        val payOrderTemp = new PayOrder();
//        payOrderTemp.setOrderStatus(thirdPlatformQueryOrder.getTradeStatus());
//        if(thirdPlatformQueryOrder.getTradeStatus().equals(DictionaryConstant.PAYMENT_ORDER_STATUS_YZF.getCode())){
//            payOrderTemp.setPayStatus(DictionaryConstant.PAY_STATUS_YFK.getCode());
//            payOrderTemp.setPayTime(LocalDateTimeUtils.convertLocalDateTimeToDate(LocalDateTimeUtils.convertStringToLocalDateTime(thirdPlatformQueryOrder.getTimeEnd(),LocalDateTimeUtils.SIMPLE_DATETIME_FORMAT)));
//            payOrderRepository.updatePayOrder(payOrder.getMcode(),payOrder.getTradeId(),payOrder.getmOrderNumber(),payOrderTemp);
//        }
//
//        //6.返回数据信息
//        val postQueryOrderResponse = new PostQueryOrderResponse(thirdPlatformQueryOrder.getMcode(),queryOrderRequest.getPayType(),payOrder.getCodeUrl(),payOrder.getTimeExpire(),payOrder.getTradeId(),thirdPlatformQueryOrder.getOuterTradeNumber(),thirdPlatformQueryOrder.getMOrderNumber(),thirdPlatformQueryOrder.getTradeStatus());
//        val sign = SignUtils.generateSign(MapBeanUtils.beanToMap(postQueryOrderResponse),mchPayInfo.getSecretKey());
//        postQueryOrderResponse.setSign(sign);
//        LogUtils.saveMchPaymentTradeLog(thirdPlatformQueryOrder.getMcode(),thirdPlatformQueryOrder.getMOrderNumber(),queryOrderRequest.getPayType(),LogUtils.LOG_DESCRIPTION_DDCS,JSON.toJSONString(postQueryOrderResponse), JSON.toJSONString(queryOrderRequest),DictionaryConstant.PAYMENT_REQUEST_TYPE_BD.getCode());
//        return postQueryOrderResponse;
//    }
//
//    /**
//     * 订单信息取消使用方法
//     * @param cannelOrderRequest
//     * @return
//     */
//    public PostCancelOrderResponse cancelOrder(PostCancelOrderRequest cannelOrderRequest){
//        //1.查询商户号信息
//        val mchPayInfo = mchPayInfoRepository.queryMchPayInfoByMcode(cannelOrderRequest.getMcode(),DictionaryConstant.PAYMENT_MCH_STATUS_SHTG.getCode());
//        if(null == mchPayInfo){
//            throw new BusinessCommonException(PaymentErrorCode.MCH_INFO_NOT_EXIST);
//        }
//
//        //2.校验签名信息
//        if(!SignUtils.isSignatureValid(MapBeanUtils.beanToMap(cannelOrderRequest),mchPayInfo.getSecretKey())){
//            throw new BusinessCommonException(PaymentErrorCode.SIGN_VALID_ERROR);
//        }
//
//        //3.查询业务订单下的所有预付单信息
//        val payOrders = payOrderRepository.queryPayOrder(cannelOrderRequest.getMcode(),cannelOrderRequest.getOrderNumber());
//        if(null != payOrders && payOrders.size() > 0){
//            //遍历预付单列表，进行订单取消
//            for(PayOrder payOrder:payOrders){
//                val mchPayChannel = mchPayChannelRepository.queryMchPayChannelByMcodeWithBlob(cannelOrderRequest.getMcode(),payOrder.getPayType());
//                val payTypeDict = payTypeDictRepository.queryEnablePayTypeDict(payOrder.getPayType());
//                //3.1 发送取消订单请求
//                val thirdPayRepository = SpringUtils.getBean(payTypeDict.getBeanName(),IThirdPayRepository.class);
//                val thirdPlatformQueryOrder = thirdPayRepository.cannelPayOrderFromThirdPlatform(payOrder,mchPayChannel);
//                //3.2 更新订单状态
//                if(("1").equals(thirdPlatformQueryOrder.getCancelStatus())){
//                    payOrderRepository.cancelPayOrder(payOrder.getMcode(),payOrder.getmOrderNumber(),payOrder.getPayType());
//                }
//            }
//        }
//        //3.查询第三方支付平台预付单信息
//        val cancelOrderResponse = new PostCancelOrderResponse(cannelOrderRequest.getMcode(),cannelOrderRequest.getOrderNumber(),"1");
//        val sign = SignUtils.generateSign(MapBeanUtils.beanToMap(cancelOrderResponse),mchPayInfo.getSecretKey());
//        cancelOrderResponse.setSign(sign);
//        LogUtils.saveMchPaymentTradeLog(cannelOrderRequest.getMcode(),cannelOrderRequest.getOrderNumber(),"",LogUtils.LOG_DESCRIPTION_DDQX,JSON.toJSONString(cancelOrderResponse), JSON.toJSONString(cannelOrderRequest),DictionaryConstant.PAYMENT_REQUEST_TYPE_BD.getCode());
//        return cancelOrderResponse;
//    }
//
//    /**
//     * 订单信息申请退款使用方法
//     * @param refundOrderRequest
//     * @return
//     */
//    public PostRefundOrderResponse refundOrder(PostRefundOrderRequest refundOrderRequest){
//        //1.查询商户号信息
//        val mchPayInfo = mchPayInfoRepository.queryMchPayInfoByMcode(refundOrderRequest.getMcode(),DictionaryConstant.PAYMENT_MCH_STATUS_SHTG.getCode());
//        if(null == mchPayInfo){
//            throw new BusinessCommonException(PaymentErrorCode.MCH_INFO_NOT_EXIST);
//        }
//
//        //2.校验签名信息
//        if(!SignUtils.isSignatureValid(MapBeanUtils.beanToMap(refundOrderRequest),mchPayInfo.getSecretKey())){
//            throw new BusinessCommonException(PaymentErrorCode.SIGN_VALID_ERROR);
//        }
//
//        //3.查询业务订单下的所有预付单信息
//        val payOrder = payOrderRepository.queryPayOrder(refundOrderRequest.getMcode(),refundOrderRequest.getOrderNumber(),refundOrderRequest.getPayType());
//        if(null == payOrder){
//            throw new BusinessCommonException(PaymentErrorCode.MCH_ORDER_NOT_EXIST);
//        }
//        val mchPayChannel = mchPayChannelRepository.queryMchPayChannelByMcodeWithBlob(refundOrderRequest.getMcode(),payOrder.getPayType());
//        val payTypeDict = payTypeDictRepository.queryEnablePayTypeDict(payOrder.getPayType());
//
//        //3.1 发送退款申请请求
//        val thirdPayRepository = SpringUtils.getBean(payTypeDict.getBeanName(),IThirdPayRepository.class);
//        val thirdPlatformRefundOrder = thirdPayRepository.refundPayOrderFromThirdPlatform(payOrder,refundOrderRequest.getRefundNumber(),refundOrderRequest.getRefundAmount(),mchPayChannel,payTypeDict);
//        //3.2 更新订单状态,并生成聚合支付平台退款单信息
//        if(("1").equals(thirdPlatformRefundOrder.getRefundStatus())){
//            String refundNotifyUrl = refundOrderRequest.getRefundNotifyUrl();
//            if(StringUtils.isEmpty(refundNotifyUrl)){
//                refundNotifyUrl = mchPayChannel.getRefundNotifyUrl();
//            }
//            if(refundOrderRequest.getPayType().equals(DictionaryConstant.PAYMENT_PAY_TYPE_ZFBSM.getCode())){
//                //支付宝申请退款后直接退款完成
//                payOrderRepository.refundPayOrder(payOrder,refundOrderRequest.getRefundNumber(),refundOrderRequest.getRefundAmount(),thirdPlatformRefundOrder.getThirdRefundNumber(),refundNotifyUrl,DictionaryConstant.ORDER_STATUS_YTK.getCode());
//            }else{
//                //其它方式申请退款，退款状态为退款中
//                payOrderRepository.refundPayOrder(payOrder,refundOrderRequest.getRefundNumber(),refundOrderRequest.getRefundAmount(),thirdPlatformRefundOrder.getThirdRefundNumber(),refundNotifyUrl,DictionaryConstant.ORDER_STATUS_TKZ.getCode());
//            }
//        }
//
//        //4.整理返回数据
//        val refundOrderResponse = new PostRefundOrderResponse();
//        BeanUtils.copyProperties(refundOrderRequest,refundOrderResponse);
//        BeanUtils.copyProperties(thirdPlatformRefundOrder,refundOrderResponse);
//        val sign = SignUtils.generateSign(MapBeanUtils.beanToMap(refundOrderResponse),mchPayInfo.getSecretKey());
//        refundOrderResponse.setSign(sign);
//        LogUtils.saveMchPaymentTradeLog(refundOrderResponse.getMcode(),refundOrderResponse.getOrderNumber(),refundOrderRequest.getPayType(),LogUtils.LOG_DESCRIPTION_SQTK,JSON.toJSONString(refundOrderResponse), JSON.toJSONString(refundOrderRequest),DictionaryConstant.PAYMENT_REQUEST_TYPE_BD.getCode());
//        return refundOrderResponse;
//    }

    /**
     * 订单信息撤销使用方法
     * @return
     */
    public PostReversePayGrantResponse reversePayGrant(PostReversePayGrantRequest reversePayGrantRequest){
        //1.查询商户号信息
        val mchPayInfo = mchPayInfoRepository.queryMchPayInfoByMcode(reversePayGrantRequest.getMcode(),DictionaryConstant.PAYMENT_MCH_STATUS_SHTG.getCode());
        if(null == mchPayInfo){
            throw new BusinessCommonException(PaymentErrorCode.MCH_INFO_NOT_EXIST);
        }

        //2.校验签名信息
        if(!SignUtils.isSignatureValid(MapBeanUtils.beanToMap(reversePayGrantRequest),mchPayInfo.getSecretKey())){
            throw new BusinessCommonException(PaymentErrorCode.SIGN_VALID_ERROR);
        }

        //3.查询业务订单下的所有预付单信息
        val grantsPayOrders = grantPayOrderRepository.queryGrantPayOrders(reversePayGrantRequest.getMcode(),reversePayGrantRequest.getOrderNumber());
        if(null != grantsPayOrders && grantsPayOrders.size() > 0){
            //遍历预付单列表，进行订单取消
            for(GrantPayOrder grantPayOrder:grantsPayOrders){
                val mchPayChannel = mchPayChannelRepository.queryMchPayChannelByMcodeWithBlob(reversePayGrantRequest.getMcode(),grantPayOrder.getPayType());
                val payTypeDict = payTypeDictRepository.queryEnablePayTypeDict(grantPayOrder.getPayType());
                //3.1 发送撤销订单请求
                val thirdPayRepository = SpringUtils.getBean(payTypeDict.getBeanName(),IThirdPayGrantRepository.class);
                val thirdPlatformReverseOrder = thirdPayRepository.reversePayGrantFromThirdPlatform(grantPayOrder,mchPayChannel);
                //3.2 更新订单状态
                if(("2").equals(thirdPlatformReverseOrder.getReverseStatus())){
                    grantPayOrderRepository.cancelGrantPayOrder(grantPayOrder.getMcode(),grantPayOrder.getmOrderNumber(),grantPayOrder.getPayType());
                }
            }
        }
        //3.查询第三方支付平台预付单信息
        val reverseOrderResponse = new PostReversePayGrantResponse(reversePayGrantRequest.getMcode(),reversePayGrantRequest.getOrderNumber(),"2");
        val sign = SignUtils.generateSign(MapBeanUtils.beanToMap(reverseOrderResponse),mchPayInfo.getSecretKey());
        reverseOrderResponse.setSign(sign);
        LogUtils.saveMchPaymentTradeLog(reverseOrderResponse.getMcode(),reverseOrderResponse.getOrderNumber(),"",LogUtils.LOG_DESCRIPTION_DDQX,JSON.toJSONString(reverseOrderResponse), JSON.toJSONString(reverseOrderResponse),DictionaryConstant.PAYMENT_REQUEST_TYPE_BD.getCode());
        return reverseOrderResponse;
    }
    
    /**
     * 预授权订单解冻使用方法
     * @return
     */
    public PostUnFreezePayGrantResponse unFreezePay(PostUnFreezePayGrantRequest unFreePayRequest){
        //1.查询商户号信息
        val mchPayInfo = mchPayInfoRepository.queryMchPayInfoByMcode(unFreePayRequest.getMcode(),DictionaryConstant.PAYMENT_MCH_STATUS_SHTG.getCode());
        if(null == mchPayInfo){
            throw new BusinessCommonException(PaymentErrorCode.MCH_INFO_NOT_EXIST);
        }
        
        //2.校验签名信息
        if(!SignUtils.isSignatureValid(MapBeanUtils.beanToMap(unFreePayRequest),mchPayInfo.getSecretKey())){
            throw new BusinessCommonException(PaymentErrorCode.SIGN_VALID_ERROR);
        }
        
        //3.查询业务订单下的所有预付单信息
        val grantPayOrder = grantPayOrderRepository.queryPayOrderByNumber(unFreePayRequest.getOrderNumber(),unFreePayRequest.getPayType());
        val unFreezePayGrantResponse = new PostUnFreezePayGrantResponse(unFreePayRequest.getMcode(),unFreePayRequest.getOrderNumber(),"2");
        //遍历预付单列表，进行订单取消
        val mchPayChannel = mchPayChannelRepository.queryMchPayChannelByMcodeWithBlob(unFreePayRequest.getMcode(),grantPayOrder.getPayType());
        val payTypeDict = payTypeDictRepository.queryEnablePayTypeDict(grantPayOrder.getPayType());
        
        //校验剩余金额是否满足解冻要求
        Long grantAmount = grantPayOrder.getGrantAmount()-grantPayOrder.getUnfreezeAmount();
        if(null != unFreePayRequest.getAmount() && grantAmount < unFreePayRequest.getAmount()){
            throw new BusinessCommonException(PaymentErrorCode.FREEZE_AMOUNT_LESS);
        }
        
        //3.1 发送撤销订单请求
        val thirdPayRepository = SpringUtils.getBean(payTypeDict.getBeanName(),IThirdPayGrantRepository.class);
        val thirdPlatformUnFreezeGrant = thirdPayRepository.unfreezePayFromThirdPlatform(unFreePayRequest.getAmount(),grantPayOrder,mchPayChannel);
        //3.2 更新订单状态
        if(("2").equals(thirdPlatformUnFreezeGrant.getUnFreezeStatus())){
            GrantPayOrder updateGrantPayOrder = new GrantPayOrder();
            updateGrantPayOrder.setMcode(grantPayOrder.getMcode());
            updateGrantPayOrder.setmOrderNumber(grantPayOrder.getmOrderNumber());
            updateGrantPayOrder.setPayType(grantPayOrder.getPayType());
            updateGrantPayOrder.setUnfreezeAmount(grantPayOrder.getUnfreezeAmount()+thirdPlatformUnFreezeGrant.getAmount());
            updateGrantPayOrder.setUngrantTime(DateUtils.parse(thirdPlatformUnFreezeGrant.getUnFreezeTime()));
            grantPayOrderRepository.unFreezeGrantPayOrder(updateGrantPayOrder);
            
            unFreezePayGrantResponse.setUnFreezeAmount(thirdPlatformUnFreezeGrant.getAmount());
            unFreezePayGrantResponse.setUnFreezeTime(thirdPlatformUnFreezeGrant.getUnFreezeTime());
        }
        //3.查询第三方支付平台预付单信息
       
        val sign = SignUtils.generateSign(MapBeanUtils.beanToMap(unFreezePayGrantResponse),mchPayInfo.getSecretKey());
        unFreezePayGrantResponse.setSign(sign);
        LogUtils.saveMchPaymentTradeLog(unFreezePayGrantResponse.getMcode(),unFreezePayGrantResponse.getOrderNumber(),"",LogUtils.LOG_DESCRIPTION_DDQX,JSON.toJSONString(unFreezePayGrantResponse), JSON.toJSONString(unFreezePayGrantResponse),DictionaryConstant.PAYMENT_REQUEST_TYPE_BD.getCode());
        return unFreezePayGrantResponse;
    }
    
    /**
     * 预授权订单查询使用方法
     * @return
     */
    public PostQueryPayGrantResponse queryPayGrant(PostQueryPayGrantRequest queryPayGrantRequest){
        //1.查询商户号信息
        val mchPayInfo = mchPayInfoRepository.queryMchPayInfoByMcode(queryPayGrantRequest.getMcode(),DictionaryConstant.PAYMENT_MCH_STATUS_SHTG.getCode());
        if(null == mchPayInfo){
            throw new BusinessCommonException(PaymentErrorCode.MCH_INFO_NOT_EXIST);
        }
        
        //2.校验签名信息
        if(!SignUtils.isSignatureValid(MapBeanUtils.beanToMap(queryPayGrantRequest),mchPayInfo.getSecretKey())){
            throw new BusinessCommonException(PaymentErrorCode.SIGN_VALID_ERROR);
        }
        
        //3.查询业务订单下的所有预付单信息
        val grantPayOrder = grantPayOrderRepository.queryPayOrderByNumber(queryPayGrantRequest.getOrderNumber(),queryPayGrantRequest.getPayType());
        
        //遍历预付单列表，进行订单取消
        val mchPayChannel = mchPayChannelRepository.queryMchPayChannelByMcodeWithBlob(queryPayGrantRequest.getMcode(),grantPayOrder.getPayType());
        val payTypeDict = payTypeDictRepository.queryEnablePayTypeDict(grantPayOrder.getPayType());
        
        //3.1 发送撤销订单请求
        val thirdPayRepository = SpringUtils.getBean(payTypeDict.getBeanName(),IThirdPayGrantRepository.class);
        val thirdPlatformQueryPayGrant = thirdPayRepository.queryPayGrantFromThirdPlatform(grantPayOrder,mchPayChannel);
        
        //3.查询第三方支付平台预付单信息,整理返回数据
        val queryPayGrantResponse = new PostQueryPayGrantResponse();
        BeanUtils.copyProperties(thirdPlatformQueryPayGrant,queryPayGrantResponse);
        queryPayGrantResponse.setGrantStatus(grantPayOrder.getGrantStatus());
        queryPayGrantResponse.setOrderNumber(queryPayGrantRequest.getOrderNumber());
        
        val sign = SignUtils.generateSign(MapBeanUtils.beanToMap(queryPayGrantResponse),mchPayInfo.getSecretKey());
        queryPayGrantResponse.setSign(sign);
        LogUtils.saveMchPaymentTradeLog(queryPayGrantRequest.getMcode(),queryPayGrantRequest.getOrderNumber(),"",LogUtils.LOG_DESCRIPTION_DDQX,JSON.toJSONString(queryPayGrantRequest), JSON.toJSONString(queryPayGrantResponse),DictionaryConstant.PAYMENT_REQUEST_TYPE_BD.getCode());
        return queryPayGrantResponse;
    }
    
    /**
     * 预授权订单转支付使用方法
     * @return
     */
    public PostGrantToPayResponse grantToPay(PostGrantToPayRequest grantToPayRequest){
        //1.查询商户号信息
        val mchPayInfo = mchPayInfoRepository.queryMchPayInfoByMcode(grantToPayRequest.getMcode(),DictionaryConstant.PAYMENT_MCH_STATUS_SHTG.getCode());
        if(null == mchPayInfo){
            throw new BusinessCommonException(PaymentErrorCode.MCH_INFO_NOT_EXIST);
        }
        
        //2.校验签名信息
        if(!SignUtils.isSignatureValid(MapBeanUtils.beanToMap(grantToPayRequest),mchPayInfo.getSecretKey())){
            throw new BusinessCommonException(PaymentErrorCode.SIGN_VALID_ERROR);
        }
        
        //3.查询业务订单下的所有预付单信息
        val grantPayOrder = grantPayOrderRepository.queryPayOrderByNumber(grantToPayRequest.getGrantOrderNumber(),grantToPayRequest.getPayType());
        
        //遍历预付单列表，进行订单取消
        val mchPayChannel = mchPayChannelRepository.queryMchPayChannelByMcodeWithBlob(grantToPayRequest.getMcode(),grantPayOrder.getPayType());
        val payTypeDict = payTypeDictRepository.queryEnablePayTypeDict(grantPayOrder.getPayType());
        
        //3.1 发送撤销订单请求
        val thirdPayRepository = SpringUtils.getBean(payTypeDict.getBeanName(),IThirdPayGrantRepository.class);
    
        grantPayOrder.setmPayOrderNumber(grantToPayRequest.getOrderNumber());
        grantPayOrder.setPayAmount(grantToPayRequest.getPayAmount());
        val thirdPlatformGrantToPay = thirdPayRepository.grantToPayFromThirdPlatform(grantToPayRequest,grantPayOrder,mchPayChannel,payTypeDict);
        grantPayOrder.setOuterPayOrderNumber(thirdPlatformGrantToPay.getOuterPayOrderNumber());
        grantPayOrder.setPayTime(DateUtils.parse(thirdPlatformGrantToPay.getPaidTime()));
        if(thirdPlatformGrantToPay.getPayStatus().equals(DictionaryConstant.PAY_STATUS_YFK.getCode())){
            grantPayOrder.setGrantStatus(DictionaryConstant.PAY_GRANT_STATUS_ZF.getCode());
        }
        grantPayOrderRepository.updateOrderPayStatus(grantPayOrder,grantToPayRequest.getMcode(),grantToPayRequest.getGrantOrderNumber(),grantToPayRequest.getPayType());
        //3.查询第三方支付平台预付单信息,整理返回数据
        val grantToPayResponse = new PostGrantToPayResponse();
        BeanUtils.copyProperties(thirdPlatformGrantToPay,grantToPayResponse);
        grantToPayResponse.setPayAmount(grantToPayRequest.getPayAmount());
        grantToPayResponse.setGrantOrderNumber(thirdPlatformGrantToPay.getMOrderNumber());
        grantToPayResponse.setOrderNumber(grantToPayRequest.getOrderNumber());
        
        val sign = SignUtils.generateSign(MapBeanUtils.beanToMap(grantToPayResponse),mchPayInfo.getSecretKey());
        grantToPayResponse.setSign(sign);
        LogUtils.saveMchPaymentTradeLog(grantToPayRequest.getMcode(),grantToPayRequest.getOrderNumber(),grantToPayRequest.getPayType(),LogUtils.LOG_DESCRIPTION_DDQX,JSON.toJSONString(grantToPayRequest), JSON.toJSONString(grantToPayResponse),DictionaryConstant.PAYMENT_REQUEST_TYPE_BD.getCode());
        return grantToPayResponse;
    }
    
    /**
     * 订单信息申请退款使用方法
     * @param grantPayRefundRequest
     * @return
     */
    public PostGrantPayRefundResponse grantPayRefund(PostGrantPayRefundRequest grantPayRefundRequest){
        //1.查询商户号信息
        val mchPayInfo = mchPayInfoRepository.queryMchPayInfoByMcode(grantPayRefundRequest.getMcode(),DictionaryConstant.PAYMENT_MCH_STATUS_SHTG.getCode());
        if(null == mchPayInfo){
            throw new BusinessCommonException(PaymentErrorCode.MCH_INFO_NOT_EXIST);
        }
        
        //2.校验签名信息
        if(!SignUtils.isSignatureValid(MapBeanUtils.beanToMap(grantPayRefundRequest),mchPayInfo.getSecretKey())){
            throw new BusinessCommonException(PaymentErrorCode.SIGN_VALID_ERROR);
        }
    
        //3.查询业务订单下的所有预付单信息
        val grantPayOrder = grantPayOrderRepository.queryPayOrderByPayNumber(grantPayRefundRequest.getOrderNumber(),grantPayRefundRequest.getPayType());
        if(null == grantPayOrder){
            throw new BusinessCommonException(PaymentErrorCode.MCH_ORDER_NOT_EXIST);
        }
        val mchPayChannel = mchPayChannelRepository.queryMchPayChannelByMcodeWithBlob(grantPayRefundRequest.getMcode(),grantPayOrder.getPayType());
        val payTypeDict = payTypeDictRepository.queryEnablePayTypeDict(grantPayOrder.getPayType());
        
        //3.1 发送退款申请请求
        val thirdPayRepository = SpringUtils.getBean(payTypeDict.getBeanName(),IThirdPayGrantRepository.class);
        val thirdPlatformRefundOrder = thirdPayRepository.refundPayOrderFromThirdPlatform(grantPayOrder,grantPayRefundRequest.getRefundNumber(),grantPayRefundRequest.getRefundAmount(),mchPayChannel,payTypeDict);
        //3.2 更新订单状态,并生成聚合支付平台退款单信息
        String refundNotifyUrl = grantPayRefundRequest.getRefundNotifyUrl();
        if(StringUtils.isEmpty(refundNotifyUrl)){
            refundNotifyUrl = mchPayChannel.getRefundNotifyUrl();
        }
        grantPayOrderRepository.refundPayOrder(grantPayOrder,grantPayRefundRequest.getRefundNumber(),grantPayRefundRequest.getRefundAmount(),thirdPlatformRefundOrder.getThirdRefundNumber(),refundNotifyUrl,DictionaryConstant.ORDER_STATUS_YTK.getCode());
        
        //4.整理返回数据
        val refundOrderResponse = new PostGrantPayRefundResponse();
        BeanUtils.copyProperties(grantPayRefundRequest,refundOrderResponse);
        BeanUtils.copyProperties(thirdPlatformRefundOrder,refundOrderResponse);
        val sign = SignUtils.generateSign(MapBeanUtils.beanToMap(refundOrderResponse),mchPayInfo.getSecretKey());
        refundOrderResponse.setSign(sign);
        LogUtils.saveMchPaymentTradeLog(refundOrderResponse.getMcode(),refundOrderResponse.getOrderNumber(),grantPayRefundRequest.getPayType(),LogUtils.LOG_DESCRIPTION_SQTK,JSON.toJSONString(refundOrderResponse), JSON.toJSONString(grantPayRefundRequest),DictionaryConstant.PAYMENT_REQUEST_TYPE_BD.getCode());
        return refundOrderResponse;
    }
}
