package com.thinkgem.jeesite.modules.pay.service;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.google.common.collect.Maps;
import com.thinkgem.jeesite.common.baseBean.Request;
import com.thinkgem.jeesite.common.baseBean.Response;
import com.thinkgem.jeesite.common.config.Global;
import com.thinkgem.jeesite.common.constant.ComCode;
import com.thinkgem.jeesite.common.utils.DateUtils;
import com.thinkgem.jeesite.common.utils.IdGen;
import com.thinkgem.jeesite.common.utils.StringUtils;
import com.thinkgem.jeesite.modules.commonError.MyException;
import com.thinkgem.jeesite.modules.pay.alipay.service.AlipayService;
import com.thinkgem.jeesite.modules.pay.dao.PayApiDao;
import com.thinkgem.jeesite.modules.pay.dao.RateDao;
import com.thinkgem.jeesite.modules.pay.entity.*;
import com.thinkgem.jeesite.modules.pay.huanqiuhuiju.service.HuanqiuhuijuService;
import com.thinkgem.jeesite.modules.pay.juhezhong.dto.JuhezhongDto;
import com.thinkgem.jeesite.modules.pay.juhezhong.dto.PayBackDto;
import com.thinkgem.jeesite.modules.pay.juhezhong.dto.QuickDto;
import com.thinkgem.jeesite.modules.pay.juhezhong.service.JuHeZhongPayIntegralService;
import com.thinkgem.jeesite.modules.pay.juhezhong.service.JuHeZhongPayJFenService;
import com.thinkgem.jeesite.modules.pay.juhezhong.service.JuHeZhongPayService;
import com.thinkgem.jeesite.modules.pay.juhezhong.utils.MakeOrderNum;
import com.thinkgem.jeesite.modules.pay.pinganbank.PingAnBankService;
import com.thinkgem.jeesite.modules.pay.pinganbank.dto.PingAnBankDto;
import com.thinkgem.jeesite.modules.sys.dao.UserDao;
import com.thinkgem.jeesite.modules.sys.entity.Dict;
import com.thinkgem.jeesite.modules.sys.utils.DictUtils;
import com.thinkgem.jeesite.modules.user.bean.JuHeZhongPayRequest;
import com.thinkgem.jeesite.modules.user.bean.UserRequest;
import com.thinkgem.jeesite.modules.user.dao.UserApiDao;
import com.thinkgem.jeesite.modules.user.entity.*;
import com.thinkgem.jeesite.modules.user.service.UserApiService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;

/**
 * 支付相关
 */

@Service
@Lazy(false)
@Transactional(readOnly = true)
public class PayApiService {
    /**
     * log
     */
    private static Logger logger = LoggerFactory.getLogger(PayApiService.class);
    @Autowired
    private PayApiDao payDao;
    @Autowired
    private UserApiService userService;
    @Autowired
    private JuHeZhongPayService juHeZhongPayService;

    @Autowired
    private JuHeZhongPayIntegralService juHeZhongPayIntegralService;

    @Autowired
    private JuHeZhongPayJFenService juHeZhongPayJFenService;

    @Autowired
    private HuanqiuhuijuService huanqiuhuijuService;

    @Autowired
    private AlipayService alipayService;

    @Autowired
    private PingAnBankService pingAnBankService;

    @Autowired
    private BenefitSevice benefitSevice;

    @Autowired
    private RateDao rateDao;

    @Autowired
    private UserApiDao userDao;


    /**
     * 快捷支付（分为不同的渠道）
     *
     * @param request
     * @return
     * @throws MyException
     * @throws Exception
     */
    @Transactional(readOnly = false)
    public PayBackDto quickPay(JuHeZhongPayRequest request) throws MyException, Exception {
        if (ComCode.PAYCHANNEL_HL2.equals(request.getPayChannel())) {
            logger.debug("进入到HL2通道");
            PayBackDto payBackDto = this.jFenPayJuhezhong(request);
            payBackDto.setIsUrl("0");
            return payBackDto;
        }
        // 1. 根据入参获取用户详情信息，包括支付卡片信息
        UserEntity userEntity = userService.getUserInfo(new Request(request.getSubMerchantCode()));
        userEntity = userService.getUserDetailInfo(userEntity);
        UserRequest userRequest = new UserRequest();
        userRequest.setSubMerchantCode(request.getSubMerchantCode());

        CardEntity cardEntity = userService.getDebitCardByUserCode(userRequest);
        userEntity.getUserDetail().setCard(cardEntity);
        //获取当前渠道当日剩余额度
        BigDecimal limitNumber = getLimitNumber(userEntity.getLevel(), userEntity.getCode(), request.getPayChannel());
        if (BigDecimal.valueOf(Double.valueOf(request.getAmount())).compareTo(limitNumber) > 0) {
            throw new MyException("超出额度");
        }
        // 2. 创建支付订单信息，并保存
        String code = IdGen.randomBase62(64);
        String payNo = ComCode.YYYYMMDDHHMM.format(new Date()) + IdGen.randomBase62(8); // 订单号
        String payCode = IdGen.randomBase62(64);
        DecimalFormat df = new DecimalFormat("######0.00");
        String amount = df.format(Double.valueOf(request.getAmount()));
        // 4. JuHeZhong支付
        PayBackDto payBackDto = new PayBackDto();
        if (ComCode.PAYCHANNEL_HL1.equals(request.getPayChannel())) {
            OrderEntity orderEntity = new OrderEntity(code, request.getSubMerchantCode(), payNo, payCode, "quick", request.getPayChannel(), "1", amount, request.getSubject(), "", String.valueOf("D".equalsIgnoreCase(userEntity.getUserDetail().getCard().getCardType()) ? 5 : ("C".equalsIgnoreCase(userEntity.getUserDetail().getCard().getCardType()) ? 6 : 0)), request.getCardCode());
            addUserBenefits(userEntity, orderEntity, code, request);
//            payDao.saveOrderInfo(orderEntity);
//            // 3. 创建分润信息，并保存
//            Map<String, String> userBenefits = getUserBenefit(userEntity, request);
//            for (String key : userBenefits.keySet()) {
//                String benefitCode = IdGen.randomBase62(64);
//                BenefitEntity benefitEntity = new BenefitEntity(benefitCode, request.getSubMerchantCode(), code, request.getPayChannel(), "0", "A", userBenefits.get(key), "");
//                benefitEntity.setAmount(String.valueOf(Double.valueOf(benefitEntity.getAmount())));
//                benefitEntity.setPayMethod(orderEntity.getPayMethod());
//                payDao.saveBenefitInfo(benefitEntity);
//            }

            // 获取支付卡号
            CardEntity cardEntityPay = userService.getCardInfo(request);
            payBackDto = this.payJuhezhong(request, userEntity, orderEntity, cardEntityPay);
        } else if (ComCode.PAYCHANNEL_HL3.equals(request.getPayChannel())) {
            OrderEntity orderEntity = new OrderEntity(code, request.getSubMerchantCode(), payNo, payCode, "quick", request.getPayChannel(), "1", amount, request.getSubject(), "", String.valueOf("D".equalsIgnoreCase(userEntity.getUserDetail().getCard().getCardType()) ? 5 : ("C".equalsIgnoreCase(userEntity.getUserDetail().getCard().getCardType()) ? 6 : 0)), request.getCardCode());
            addUserBenefits(userEntity, orderEntity, code, request);
//            payDao.saveOrderInfo(orderEntity);
//            // 3. 创建分润信息，并保存
//            Map<String, String> userBenefits = getUserBenefit(userEntity, request);
//            for (String key : userBenefits.keySet()) {
//                String benefitCode = IdGen.randomBase62(64);
//                BenefitEntity benefitEntity = new BenefitEntity(benefitCode, request.getSubMerchantCode(), code, request.getPayChannel(), "0", "A", userBenefits.get(key), "");
//                benefitEntity.setAmount(String.valueOf(Double.valueOf(benefitEntity.getAmount())));
//                benefitEntity.setPayMethod(orderEntity.getPayMethod());
//                payDao.saveBenefitInfo(benefitEntity);
//            }

            // 获取支付卡号
            CardEntity cardEntityPay = userService.getCardInfo(request);
            if (!"C".equals(cardEntityPay.getCardType())) {
                payBackDto.setMessage("只能用信用卡支付");
            } else if (cardEntityPay.getSupportPayChannel() == null || !cardEntityPay.getSupportPayChannel().contains(request.getPayChannel())) {
                payBackDto.setMessage("不支持" + cardEntityPay.getBankName());
            } else {
                payBackDto = this.quickPayJuHeZhongIntegralPay(userEntity, orderEntity, request, cardEntityPay);
            }

        } else if (ComCode.PAYCHANNEL_HUANQIUHUIJU.equals(request.getPayChannel())) {
            OrderEntity orderEntity = new OrderEntity(code, request.getSubMerchantCode(), payNo, payCode, "quick", request.getPayChannel(), "1", amount, request.getSubject(), "", String.valueOf("D".equalsIgnoreCase(userEntity.getUserDetail().getCard().getCardType()) ? 5 : ("C".equalsIgnoreCase(userEntity.getUserDetail().getCard().getCardType()) ? 6 : 0)), request.getCardCode());
            addUserBenefits(userEntity, orderEntity, code, request);
//            payDao.saveOrderInfo(orderEntity);
//            // 3. 创建分润信息，并保存
//            Map<String, String> userBenefits = getUserBenefit(userEntity, request);
//            for (String key : userBenefits.keySet()) {
//                String benefitCode = IdGen.randomBase62(64);
//                BenefitEntity benefitEntity = new BenefitEntity(benefitCode, request.getSubMerchantCode(), code, request.getPayChannel(), "0", "A", userBenefits.get(key), "");
//                benefitEntity.setAmount(String.valueOf(Double.valueOf(benefitEntity.getAmount())));
//                benefitEntity.setPayMethod(orderEntity.getPayMethod());
//                payDao.saveBenefitInfo(benefitEntity);
//            }

            // 获取支付卡号
            CardEntity cardEntityPay = userService.getCardInfo(request);

            payBackDto = this.huanqiuhujuPay(userEntity, orderEntity, request, cardEntityPay);
        } else {
            OrderEntity orderEntity = new OrderEntity(code, request.getSubMerchantCode(), payNo, payCode, "quick", ComCode.PAYCHANNEL_HL3, "1", amount, request.getSubject(), "", String.valueOf("D".equalsIgnoreCase(userEntity.getUserDetail().getCard().getCardType()) ? 5 : ("C".equalsIgnoreCase(userEntity.getUserDetail().getCard().getCardType()) ? 6 : 0)), request.getCardCode());
            addUserBenefits(userEntity, orderEntity, code, request);
            //            payDao.saveOrderInfo(orderEntity);
//            // 3. 创建分润信息，并保存
//            Map<String, String> userBenefits = getUserBenefit(userEntity, request);
//            for (String key : userBenefits.keySet()) {
//                String benefitCode = IdGen.randomBase62(64);
//                BenefitEntity benefitEntity = new BenefitEntity(benefitCode, request.getSubMerchantCode(), code, request.getPayChannel(), "0", "A", userBenefits.get(key), "");
//                benefitEntity.setAmount(String.valueOf(Double.valueOf(benefitEntity.getAmount())));
//                benefitEntity.setPayMethod(orderEntity.getPayMethod());
//                payDao.saveBenefitInfo(benefitEntity);
//            }

            // 获取支付卡号
            CardEntity cardEntityPay = userService.getCardInfo(request);
            if (!"C".equals(cardEntityPay.getCardType())) {
                payBackDto.setMessage("只能用信用卡支付");
            } else if (cardEntityPay.getSupportPayChannel() == null || !cardEntityPay.getSupportPayChannel().contains("ComCode.PAYCHANNEL_HL3,")) {
                payBackDto.setMessage("不支持" + cardEntityPay.getBankName());
            } else {
                payBackDto = this.quickPayJuHeZhongIntegralPay(userEntity, orderEntity, request, cardEntityPay);
            }
        }


        return payBackDto;
    }


    /**
     * 共用的分润信息
     *
     * @param userEntity
     * @param orderEntity
     * @param code
     * @param request
     */
    @Transactional(readOnly = false)
    public void addUserBenefits(UserEntity userEntity, OrderEntity orderEntity, String code, JuHeZhongPayRequest request) {
        payDao.saveOrderInfo(orderEntity);
        // 3. 创建分润信息，并保存
        Map<String, String> userBenefits = getUserBenefit(userEntity, request);
        for (String key : userBenefits.keySet()) {
            String benefitCode = IdGen.randomBase62(64);
            BenefitEntity benefitEntity = new BenefitEntity(benefitCode, key, code, request.getPayChannel(), "0", "A", userBenefits.get(key), "");
            benefitEntity.setAmount(String.valueOf(Double.valueOf(benefitEntity.getAmount())));
            benefitEntity.setPayMethod(orderEntity.getPayMethod());
            payDao.saveBenefitInfo(benefitEntity);
        }
    }

    /*
     * 以下为类内使用方法
     */

    /**
     * JuHeZhong 无积分快捷支付
     *
     * @param userEntity
     * @param request
     * @throws Exception
     */
    public PayBackDto quickPayJuHeZhongPay(UserEntity userEntity, OrderEntity orderEntity, JuHeZhongPayRequest request, CardEntity cardEntity) throws Exception {
        // 快捷支付
//        ApiQuickPayDto quickPayDto = new ApiQuickPayDto();
//        quickPayDto.setMerchantId(ComCode.MERCHANT_ID);
//        quickPayDto.setOrderId(orderEntity.getPayCode()); // 将订单的支付号传给第三方平台
//        quickPayDto.setSubMchId(userEntity.getUserDetail().getCard().getSubMerchantId());//子商户号
//        quickPayDto.setAmount(Long.parseLong(request.getAmount()));
//        quickPayDto.setBody(request.getSubject());
//        quickPayDto.setType("D".equalsIgnoreCase(userEntity.getUserDetail().getCard().getCardType()) ? 5 : ("C".equalsIgnoreCase(userEntity.getUserDetail().getCard().getCardType()) ? 6 : 0));
//        quickPayDto.setAccName(userEntity.getUserDetail().getRealName());
//        quickPayDto.setAccNo(userEntity.getUserDetail().getCard().getCardNo());
//        quickPayDto.setMobile(userEntity.getUserDetail().getCard().getCardMobile());
//        quickPayDto.setIdNo(userEntity.getUserDetail().getIdCard());
//
//
//        quickPayDto.setAccName("聂换换");
//        quickPayDto.setAccNo("6217000180000770507");
//        quickPayDto.setMobile("13722537737");
//        quickPayDto.setIdNo("130434199212214429");
//        quickPayDto.setFrontUrl("");// 前台地址
//        quickPayDto.setNotifyUrl("");// 通知url
//        quickPayDto.setTimestamp(System.currentTimeMillis());
//        quickPayDto.setMerchantKey(ComCode.MERCHANT_KEY);


        QuickDto quickDto = new QuickDto();
        quickDto.setTrxType(3);
        quickDto.setMerchantId(ComCode.MERCHANT_ID);
        quickDto.setOrderId(orderEntity.getPayCode()); // 将订单的支付号传给第三方平台
        quickDto.setAmount(Long.parseLong(request.getAmount()) * 100);

        // 获取支付卡号
        quickDto.setBankNo(cardEntity.getCardNo()); // 支付卡号

        quickDto.setSettleBankName(userEntity.getUserDetail().getCard().getBelongBank());
        quickDto.setSettleBankNo(userEntity.getUserDetail().getCard().getCardNo());
        quickDto.setSettleBankPhone(userEntity.getUserDetail().getCard().getCardMobile());
        quickDto.setName(userEntity.getUserDetail().getRealName());
        quickDto.setCertificateCode(userEntity.getUserDetail().getIdCard());

        quickDto.setType("D".equalsIgnoreCase(userEntity.getUserDetail().getCard().getCardType()) ? 5 : ("C".equalsIgnoreCase(userEntity.getUserDetail().getCard().getCardType()) ? 6 : 0));

        RateEntity rateEntity = new RateEntity();
        rateEntity.setUserLevel(userEntity.getLevel());
        rateEntity.setPayMethod("quick");
        rateEntity.setPayChannel(ComCode.PAYCHANNEL_HL1);
        rateEntity = userService.getRateByLevel(rateEntity);
        if (rateEntity != null) {
            double userFee = Long.parseLong(request.getAmount()) * 100 * Double.valueOf(rateEntity.getRate());
            if (userFee < 100) {
                userFee = 100;
            }
            BigDecimal bigDecimal = new BigDecimal(100 + Double.valueOf(Global.getConfig("pay.y")) * 100);
            quickDto.setUserFee(bigDecimal); // 手续费 单位：分 ，D0 业务必传

        } else {
            quickDto.setUserFee(new BigDecimal(0));
        }
        quickDto.setFrontUrl(Global.getConfig("project.access.url") + "/api/pay/notifyPay");// 前台地址
        quickDto.setNotifyUrl(Global.getConfig("project.access.url") + "/api/pay/notifyPay");// 通知url
        quickDto.setTimestamp(System.currentTimeMillis());
        quickDto.setMerchantKey(ComCode.MERCHANT_KEY);
        JSONObject jsonObject = juHeZhongPayService.quickPay(quickDto);
        System.out.println(jsonObject.toString());
        PayBackDto payBackDto = new PayBackDto();
        if (!"0000".equals(jsonObject.getString("code"))) {
            throw new MyException(jsonObject.getString("msg"));

        } else {
            payBackDto.setUrl(jsonObject.getString("url"));
        }
        return payBackDto;
    }


    /**
     * JuHeZhong积分快捷支付
     *
     * @param userEntity
     * @param request
     * @throws Exception
     */
    public PayBackDto quickPayJuHeZhongIntegralPay(UserEntity userEntity, OrderEntity orderEntity, JuHeZhongPayRequest request, CardEntity cardEntity) throws Exception {
        UserSubMchId userSubMchId = new UserSubMchId();
        userSubMchId.setPayChannel(ComCode.PAYCHANNEL_HL3);
        userSubMchId.setUserCode(userEntity.getCode());
        userSubMchId = userService.getUserSubmchid(userSubMchId);
        String subMchId = null;
        if (userSubMchId == null) {
            UserRequest userRequest = new UserRequest();
            userRequest.setSubMerchantCode(request.getSubMerchantCode());
            userRequest.setBelongBank(userEntity.getUserDetail().getCard().getBelongBank());
            userRequest.setRealName(userEntity.getUserDetail().getRealName());
            userRequest.setCardNo(userEntity.getUserDetail().getCard().getCardNo());
            userRequest.setMobile(userEntity.getMobile());
            userRequest.setIdCard(userEntity.getUserDetail().getIdCard());
            userRequest.setCardPlace(userEntity.getUserDetail().getCard().getCardPlace());
            subMchId = userService.quickPayHandleJuhezhong(userRequest, "", userEntity.getLevel());
            userSubMchId = new UserSubMchId();
            userSubMchId.setPayChannel(ComCode.PAYCHANNEL_HL3);
            userSubMchId.setUserCode(userEntity.getCode());
            userSubMchId.setSubmchid(subMchId);
            userService.addUserSubmchid(userSubMchId);
        } else {
            subMchId = userSubMchId.getSubmchid();
        }
        JSONObject dto = new JSONObject();

        dto.put("serviceType", 4);// 服务类型
        dto.put("orderId", orderEntity.getPayCode());//订单号
        dto.put("amount", Long.parseLong(request.getAmount()) * 100);//交易金额
        dto.put("merchantId", ComCode.INTEGRAL_MERCHANT_ID);//商户号
//        dto.put("subMchId", userEntity.getUserDetail().getCard().getSubMerchantId());//由系统分配的商户号
        dto.put("subMchId", subMchId);
        dto.put("accNo", cardEntity.getCardNo());//开卡 唯一标识
//        dto.put("accNo", "6210210010501799229");//开卡 唯一标识
        dto.put("mobile", cardEntity.getCardMobile());

        dto.put("productName", "收款");//标题
        dto.put("notifyUrl", Global.getConfig("project.access.url") + "/api/pay/notifyPay");//支付完成  异步通知结果
        dto.put("frontUrl", Global.getConfig("project.access.url") + "/api/pay/notifyPay");//返回商户页面
        dto.put("merchantKey", ComCode.INTEGRAL_MERCHANT_KEY);//商户key
        dto.put("timestamp", System.currentTimeMillis());//时间戳
        System.out.println(dto.toJSONString());
        JSONObject jsonObject = juHeZhongPayIntegralService.quickPayHandle(dto);

        System.out.println(jsonObject.toString());
        PayBackDto payBackDto = new PayBackDto();
        if (!"0000".equals(jsonObject.getString("code"))) {
            throw new MyException(jsonObject.getString("msg"));

        } else {
            payBackDto.setUrl(jsonObject.getString("url"));
        }
        return payBackDto;
    }

    //C黄金 D白银 E青铜
    //根据分润变化重新写的分润方法
    public Map<String, String> getUserBenefit(UserEntity userEntity, JuHeZhongPayRequest request) {
        Map<String, String> userBenefit = new HashMap<>();
        //用户等级为C，即黄金级别，上级用户不参与分成，直接返回
        if (userEntity.getLevel().equals("C")) {
            return userBenefit;
        }
        //该笔交易的支付方式，获取不同费率
        String payChannel = request.getPayChannel();
        //获取该笔交易的金额
        String amount = request.getAmount();
        HashMap<String, String> map = Maps.newHashMap();
        map.put("pay_channel", payChannel);
        map.put("id", userEntity.getId());
        //当前用户费率实体
        UserRateEntity userRateEntity = payDao.getUpUser(map);

        List<String> idsList = new ArrayList<>();
        //根据user表中recommendPath的值获取推荐人
        if (userEntity.getRecommendedPath() != null && userEntity.getRecommendedPath().length() > 0) {
            String[] ids = userEntity.getRecommendedPath().split(",");
            idsList = Arrays.asList(ids);
            //因只取两级推荐用户也就是取，上级，上上级，而当前字符串包含了所有的推荐层级
            //进行逆序排序，只取前两级用户id
            Collections.sort(idsList, (a, b) -> b.compareTo(a));
        }
        //获取当前用户的推荐者,只获取了上级和上上级
        //上级
        UserRateEntity upUser = null;
        if (idsList.size() > 0) {
            String upId = idsList.get(0);
            map.put("id", upId);
            upUser = payDao.getUpUser(map);
            if (upUser != null && upUser.getUserLevel().equals("C")) {
                //AC1=(A-C1)乘以X=(0.55%-0.5%)乘以X
                //当前用户（A,B只有这两种等级会给上级分成）,也就是当前用户的费率与上级用户费率的差值
                BigDecimal rateResult = BigDecimal.valueOf(Double.valueOf(userRateEntity.getRate())).subtract(BigDecimal.valueOf(Double.valueOf(upUser.getRate())));
                BigDecimal benefitResult = rateResult.multiply(BigDecimal.valueOf(Double.valueOf(amount)));
                userBenefit.put(upUser.getUserCode(), benefitResult.toString());
            }

        }
//                EE1C2=(E1-C2)乘以X=(0.55%-0.5%)乘以X
//                ED1C2=(D1-C2)乘以X=(0.52%-0.5%)乘以X
//                DE1C2=(D-C2)乘以X=(0.52%-0.5%)乘以X
//                DD1C2=(D1-C2)乘以X=(0.52%-O.5%)乘以X

//        同上级分利润一样，当前用户是C，即黄金会员时，不参与分成；上上级用户只有是黄金会员时才能参与分成，即必须为C
//        出现的分成情况只有四种：
//                1.当前用户是E(青铜)，上级用户是E1(青铜)，上上级用户是C(黄金)，上级用户费率与上上级用户费率差值
//                2.当前用户是E(青铜)，上级用户是D1(白银)，上上级用户是C(黄金)，上级用户费率与上上级用户费率差值
//                3.当前用户是D(白银)，上级用户是E1(青铜)，上上级用户是C(黄金)，当前用户费率与上上级用户费率差值
//                4.当前用户是D(白银)，上级用户是D1(白银)，上上级用户是C(黄金)，上级用户费率与上上级用户费率差值
//

        //上上级
        if (idsList.size() > 1) {
            String upUpId = idsList.get(1);
            map.put("id", upUpId);
            UserRateEntity upUpUser = payDao.getUpUser(map);
            if (upUpUser != null && upUpUser.getUserLevel().equals("C")) {
                //第一种情况
                if (userEntity.getLevel().equals("E") && upUser.getUserLevel().equals("E")) {
                    BigDecimal rateResult = BigDecimal.valueOf(Double.valueOf(upUser.getRate())).subtract(BigDecimal.valueOf(Double.valueOf(upUpUser.getRate())));
                    BigDecimal benefitResult = rateResult.multiply(BigDecimal.valueOf(Double.valueOf(amount)));
                    userBenefit.put(upUpUser.getUserCode(), benefitResult.toString());
                }
                //第二种情况
                if (userEntity.getLevel().equals("E") && upUser.getUserLevel().equals("D")) {
                    BigDecimal rateResult = BigDecimal.valueOf(Double.valueOf(upUser.getRate())).subtract(BigDecimal.valueOf(Double.valueOf(upUpUser.getRate())));
                    BigDecimal benefitResult = rateResult.multiply(BigDecimal.valueOf(Double.valueOf(amount)));
                    userBenefit.put(upUpUser.getUserCode(), benefitResult.toString());
                }

                //第三种情况
                if (userEntity.getLevel().equals("D") && upUser.getUserLevel().equals("E")) {
                    BigDecimal rateResult = BigDecimal.valueOf(Double.valueOf(userRateEntity.getRate())).subtract(BigDecimal.valueOf(Double.valueOf(upUpUser.getRate())));
                    BigDecimal benefitResult = rateResult.multiply(BigDecimal.valueOf(Double.valueOf(amount)));
                    userBenefit.put(upUpUser.getUserCode(), benefitResult.toString());
                }
                //第四种情况
                if (userEntity.getLevel().equals("D") && upUser.getUserLevel().equals("D")) {
                    BigDecimal rateResult = BigDecimal.valueOf(Double.valueOf(upUser.getRate())).subtract(BigDecimal.valueOf(Double.valueOf(upUpUser.getRate())));
                    BigDecimal benefitResult = rateResult.multiply(BigDecimal.valueOf(Double.valueOf(amount)));
                    userBenefit.put(upUpUser.getUserCode(), benefitResult.toString());
                }
            }

        }

        return userBenefit;
    }

//最初分润方法
//    public Map<String, String> getUserBenefit(UserEntity userEntity, JuHeZhongPayRequest request) {
//        Map<String, String> userBenefit = new HashMap<>();
//        String recommendedPath = "";
//        if(userEntity.getRecommendedPath()!=null && userEntity.getRecommendedPath().length()>0){
//            recommendedPath = userEntity.getRecommendedPath().substring(1);
//        }
//        String[] pathIds = (recommendedPath + userEntity.getId() + ",").split(",");
//
//
//        System.out.println("recommendedPath:"+recommendedPath);
//        System.out.println("pathIds:"+pathIds);
//
//        // 获取三级的会员
//        List<UserRateEntity> pathCDEUsers = payDao.getCDEUsers(pathIds);
//        int countLevelC = 0;
//        // 判断上级有几个黄金会员（C）
//        for (UserRateEntity entity : pathCDEUsers) {
//            // 不考虑该用户本身
//            if (entity.getUserCode().equals(userEntity.getCode())) {
//                continue;
//            }
//            if ("C".equals(entity.getUserLevel())) {
//                countLevelC++;
//            }
//        }
//        double minRate = 1;
//        int levelCPosition = 0;
//        for (UserRateEntity entity : pathCDEUsers) {
//            levelCPosition++;
//            minRate = minRate >= Double.parseDouble(entity.getRate()) ? Double.parseDouble(entity.getRate()) : minRate;
//            if (entity.getUserCode().equals(userEntity.getCode())) {
//                continue;
//            }
//            // 只有黄金会员（C）以上才分润
//            if ("C".equals(entity.getUserLevel())) {
//                double percent = countLevelC == 1 ? 1d : (levelCPosition == 2 ? 0.95 : 0.05);
//                userBenefit.put(entity.getUserCode(), String.valueOf((minRate - Double.parseDouble(entity.getRate())) > 0 ? (minRate - Double.parseDouble(entity.getRate())) * Double.parseDouble(request.getAmount()) * percent : "0"));
//            }
//        }
//
//
//        // 获取顶级管理员
//        UserRateEntity userRateEntity = new UserRateEntity();
//        userRateEntity.setPathIds(pathIds);
//        userRateEntity.setPayChannel(request.getPayChannel());
//        List<UserRateEntity> pathSABUsers = payDao.getSABUsers(userRateEntity);
//
//        if(pathSABUsers!=null && pathSABUsers.size()>0){
//            for (UserRateEntity entity : pathSABUsers) {
//                System.out.println(entity.getRate());
//                System.out.println(entity.getUserCode());
//                System.out.println(entity.getUserLevel());
//                System.out.println(request.getAmount());
//                userBenefit.put(entity.getUserCode(), String.valueOf((minRate - Double.parseDouble(entity.getRate())) * Double.parseDouble(request.getAmount())));
//                minRate = Double.valueOf(entity.getRate());
//            }
//        }
//
//        return userBenefit;
//    }

    /**
     * HL2 通道 即JFEN 开卡 需要得参数
     *
     * @param request
     * @return
     */
    public Response openCardJFen(UserRequest request) {
        Response response = new Response();

        CardEntity cardEntity = userService.getCardInfo(request);
        UserSubMchId userSubMchId = new UserSubMchId();
        userSubMchId.setUserCode(request.getSubMerchantCode());
        userSubMchId.setPayChannel(ComCode.PAYCHANNEL_HL2);
        userSubMchId = userService.getUserSubmchid(userSubMchId);
        UserEntity userEntity = userService.getUserInfo(request);
        UserDetailEntity userDetailEntity = userService.getUserDetailByCode(request.getSubMerchantCode());

        // 如果没有注册 则先注册
        if (userSubMchId == null) {
            CardEntity cardEntityDebit = userService.getCardInfoByCode(userEntity);
            JSONObject dto = new JSONObject();

            String orderId = MakeOrderNum.makeOrderNum();

            dto.put("orderId", MakeOrderNum.makeOrderNum());
//
            dto.put("serviceType", 1);
            dto.put("subMerchantName", userDetailEntity.getRealName() + System.currentTimeMillis());
            dto.put("subMerchantType", "PERSON");
            dto.put("businessLicense", userDetailEntity.getRealName() + System.currentTimeMillis());
            dto.put("legalPersonName", userDetailEntity.getRealName());

            dto.put("legalPersonID", userDetailEntity.getIdCard());
            dto.put("subMerchantPersonName", userDetailEntity.getRealName());
            dto.put("subMerchantPersonPhone", cardEntityDebit.getCardMobile());
            dto.put("bankType", "TOPRIVATE");

            dto.put("accountName", userDetailEntity.getRealName());
            dto.put("accountNo", cardEntityDebit.getCardNo());
            dto.put("bankName", cardEntityDebit.getBankName());
            dto.put("bankProv", "天津市");
            dto.put("bankCity", "天津市");
            dto.put("bankBranch", "天津市职场");

//            dto.put("bankProv",cardEntityDebit.getCity());
//            dto.put("bankCity",cardEntityDebit.getCity());
//            dto.put("bankBranch",cardEntityDebit.getCardPlace());
            dto.put("bankCode", cardEntityDebit.getBelongBank());

            dto.put("timestamp", System.currentTimeMillis());
//            dto.put("legalPersonID",userDetailEntity.getIdCard());
//            dto.put("subMerchantPersonName",userDetailEntity.getRealName());
//            dto.put("subMerchantPersonPhone",cardEntityDebit.getCardMobile());
//            dto.put("bankType","TOPRIVATE");
//
//            dto.put("accountName",userDetailEntity.getRealName());
//            dto.put("accountNo",cardEntityDebit.getCardNo());
//            dto.put("bankName",cardEntityDebit.getBankName());
//            dto.put("bankProv",cardEntityDebit.getProvince());
//            dto.put("bankCity",cardEntityDebit.getCity());
//            dto.put("bankBranch",cardEntityDebit.getCardPlace());
//            dto.put("bankCode",cardEntityDebit.getBelongBank());
//
//            dto.put("timestamp",System.currentTimeMillis());


//            dto.put("legalPersonID","130434199212214429");
//            dto.put("subMerchantPersonName","聂换换");
//            dto.put("subMerchantPersonPhone","13722537737");
//            dto.put("bankType","TOPRIVATE");
//
//            dto.put("accountName","聂换换");
//            dto.put("accountNo","6217000060031684713");
//            dto.put("bankName","中国建设银行");
//            dto.put("bankProv","天津");
//            dto.put("bankCity","天津市");
//            dto.put("bankBranch","开户地址new");
//            dto.put("bankCode","105100000017");
//
//            dto.put("timestamp",System.currentTimeMillis());

            JSONObject jsonObject = null;
            try {
                jsonObject = juHeZhongPayJFenService.merchantIn(dto);
            } catch (Exception e) {
                response.setStatus(ComCode.STATUS_CODE_9998);
                response.setMessage(ComCode.STATUS_CODE_9998_DESC);
                response.setError(e.getMessage());
                return response;
            }
            if (!"0000".equals(jsonObject.getString("code"))) {
                response.setStatus(ComCode.STATUS_CODE_9998);
                response.setMessage(jsonObject.getString("msg"));
                return response;
            }
            String subMchId = jsonObject.getString("subMchId");
            userSubMchId.setUserCode(request.getSubMerchantCode());
            userSubMchId.setPayChannel(ComCode.PAYCHANNEL_HL2);
            userSubMchId.setSubmchid(subMchId);
            userService.addUserSubmchid(userSubMchId);
        }

        // 获取费率
        RateEntity rateEntity = new RateEntity();
        rateEntity.setUserLevel(userEntity.getLevel());
        rateEntity.setPayChannel(ComCode.PAYCHANNEL_HL2);
        rateEntity.setPayMethod("quick");
        rateEntity = userService.getRateByLevel(rateEntity);


        JSONObject dto = new JSONObject();
        dto.put("orderId", MakeOrderNum.makeOrderNum());
        dto.put("merchantId", ComCode.JFEN_MERCHANT_ID);
        dto.put("serviceType", "8");
        dto.put("subMchId", userSubMchId.getSubmchid());
        dto.put("idType", "01");
        dto.put("idNo", userDetailEntity.getIdCard());
        if (rateEntity == null) {
            dto.put("d0Fee", "0.0043");
        } else {
            dto.put("d0Fee", rateEntity.getRate());
        }

        dto.put("accountName", userDetailEntity.getRealName());
        dto.put("accountNo", cardEntity.getCardNo());
        dto.put("mobile", cardEntity.getCardMobile());
        dto.put("notifyUrl", Global.getConfig("project.access.url") + "/api/pay/openCardCallback");
        dto.put("merchantKey", ComCode.JFEN_MERCHANT_KEY);
        dto.put("timestamp", System.currentTimeMillis());
        PayBackDto payBackDto = new PayBackDto();
        try {
            JSONObject jsonObject = juHeZhongPayJFenService.openCard(dto);
            if ("0000".equals(jsonObject.get("code"))) {
                payBackDto.setUrl(jsonObject.getString("url"));
                response.setData(payBackDto);
                response.setStatus(ComCode.STATUS_CODE_2000);
                return response;
            } else {
                payBackDto.setUrl(jsonObject.getString("url"));

                response.setData(payBackDto);
                response.setStatus(ComCode.STATUS_CODE_9998);
                response.setMessage(jsonObject.getString("msg"));
                return response;
            }

        } catch (Exception e) {
            response.setData(payBackDto);
            response.setStatus(ComCode.STATUS_CODE_9998);
            response.setMessage(ComCode.STATUS_CODE_9998_DESC);
        }

        return response;
    }

    // HL2 通道 即JFEN  发送验证码  需要的参数 SubMerchantCode\amount\cardCode\PayChannel 通道\
    @Transactional(readOnly = false)
    public Response sendMessageJFen(JuHeZhongPayRequest request) throws MyException {
        //        RateEntity rate = new RateEntity();
//        rate.setUserLevel(userEntityRequest.getLevel());
//        rate.setPayChannel(ComCode.PAYCHANNEL_HL2);
//        rate.setPayMethod("quick");//全部写死是quick
//        RateEntity rateEntity = this.getRateByLevel(rate);
//        rateEntity.setServiceType("0");
//        Thread.sleep(2000);
//        // 添加费率
//        this.merchantFeelJFen(JFenSubMchId,rateEntity);
        request.setPayMethod("quick");
        CardEntity cardEntity = userService.getCardInfoSwpaccid(request);
        UserSubMchId userSubMchId = new UserSubMchId();
        userSubMchId.setUserCode(request.getSubMerchantCode());
        userSubMchId.setPayChannel(ComCode.PAYCHANNEL_HL2);
        userSubMchId = userService.getUserSubmchid(userSubMchId);
        UserEntity userEntity = userService.getUserInfo(request);
        UserDetailEntity userDetailEntity = userService.getUserDetailByCode(request.getSubMerchantCode());
        userDetailEntity.setCard(cardEntity);
        userEntity.setUserDetail(userDetailEntity);
        //获取当前渠道当日剩余额度
        BigDecimal limitNumber = getLimitNumber(userEntity.getLevel(), userEntity.getCode(), request.getPayChannel());
        if (BigDecimal.valueOf(Double.valueOf(request.getAmount())).compareTo(limitNumber) > 0) {
            throw new MyException("超出当日额度");
        }
//         判断费率，额度等
        //获取用户对应等级费率以及每笔需要的手续费
        RateEntity gradeRate = getGradeRate(userEntity.getLevel(), request.getPayChannel());

        //获取单笔价格
        int amountHL2 = calculationAmountHL2(gradeRate);
        // 2. 创建支付订单信息，并保存
        String code = IdGen.randomBase62(64);
        String payNo = ComCode.YYYYMMDDHHMM.format(new Date()) + IdGen.randomBase62(8); // 订单号
        String payCode = IdGen.randomBase62(64);
        DecimalFormat df = new DecimalFormat("######0.00");
        String amount = df.format(Double.valueOf(request.getAmount()));
        OrderEntity orderEntity = new OrderEntity(code, request.getSubMerchantCode(), payNo, payCode, "quick", request.getPayChannel(), "1", amount, request.getSubject(), "", String.valueOf("D".equalsIgnoreCase(userDetailEntity.getCard().getCardType()) ? 5 : ("C".equalsIgnoreCase(userDetailEntity.getCard().getCardType()) ? 6 : 0)), request.getCardCode());

        //3. 分润信息
        addUserBenefits(userEntity, orderEntity, code, request);
//        payDao.saveOrderInfo(orderEntity);
//        // 3. 创建分润信息，并保存
//        Map<String, String> userBenefits = getUserBenefit(userEntity, request);
//        for (String key : userBenefits.keySet()) {
//            String benefitCode = IdGen.randomBase62(64);
//            BenefitEntity benefitEntity = new BenefitEntity(benefitCode, request.getSubMerchantCode(), code, request.getPayChannel(), "0", "A", userBenefits.get(key), "");
//            benefitEntity.setAmount(String.valueOf(Double.valueOf(benefitEntity.getAmount())));
//            benefitEntity.setPayMethod(orderEntity.getPayMethod());
//            payDao.saveBenefitInfo(benefitEntity);
//        }
        Response response = new Response();

        JSONObject dto = new JSONObject();
        dto.put("orderId", payCode); // 订单号
        dto.put("merchantId", ComCode.JFEN_MERCHANT_ID);
        dto.put("serviceType", "4");
        dto.put("subMchId", userSubMchId.getSubmchid());
        dto.put("merchantKey", ComCode.JFEN_MERCHANT_KEY);
        dto.put("timestamp", System.currentTimeMillis());
        int amountInt = (int) (Double.valueOf(request.getAmount()) * 100);
        //减去每笔手续费
        int amount2 = amountInt - amountHL2;
        dto.put("amount", amount2);
        dto.put("idNo", userDetailEntity.getIdCard());
        dto.put("accountName", userDetailEntity.getRealName());
        dto.put("accountNo", cardEntity.getCardNo());

        dto.put("mobile", cardEntity.getCardMobile());
        dto.put("swpaccid", cardEntity.getSwpaccid());
        dto.put("notifyUrl", Global.getConfig("project.access.url") + "/api/pay/openCardCallback");
        try {
            //发送短信
            JSONObject jsonObject = juHeZhongPayJFenService.quickPayHandle(dto);
//	        JSONObject jsonObject = juHeZhongPayIntegralService.quickPayHandle ( dto );
            if ("0000".equals(jsonObject.get("code"))) {
                orderEntity.setTradeNo(jsonObject.getString("trade_no"));
                payDao.updateOrderTradeNo(orderEntity);
                response.setData(orderEntity);
                response.setStatus(ComCode.STATUS_CODE_2000);
                response.setMessage(ComCode.STATUS_CODE_2000_DESC);
                return response;
            }
            response.setData(orderEntity);
            response.setStatus(ComCode.STATUS_CODE_9998);
            response.setMessage(jsonObject.getString("msg"));
            return response;
        } catch (Exception e) {
            response.setData(orderEntity);
            response.setStatus(ComCode.STATUS_CODE_9998);
            response.setMessage(ComCode.STATUS_CODE_9998_DESC);
            response.setError(e.getMessage());

        }

        return response;
    }

    // HL2 通道 即JFEN  支付  需要的参数 SubMerchantCode\payNo\passwd\cardCode \
    @Transactional(readOnly = false)
    public PayBackDto jFenPayJuhezhong(JuHeZhongPayRequest request) throws Exception {

        request.setPayMethod("quick");
        CardEntity cardEntity = userService.getCardInfoSwpaccid(request);
        UserSubMchId userSubMchId = new UserSubMchId();
        userSubMchId.setUserCode(request.getSubMerchantCode());
        userSubMchId.setPayChannel(ComCode.PAYCHANNEL_HL2);
        userSubMchId = userService.getUserSubmchid(userSubMchId);
        // 如果没有注册 则先注册
        if (userSubMchId == null) {
            throw new MyException("未开卡，请先开卡");
        }

        OrderEntity orderEntity = this.getOrder(request.getPayNo());

        PayBackDto payBackDto = new PayBackDto();
        payBackDto.setIsUrl("0");

        JSONObject dto = new JSONObject();
        dto.put("orderId", orderEntity.getPayCode()); // 非订单号，回调根据此值修改
        dto.put("merchantId", ComCode.JFEN_MERCHANT_ID);// 商户号
        dto.put("serviceType", "5");// 操作类型 5
        dto.put("subMchId", userSubMchId.getSubmchid());// 子商户号
        dto.put("merchantKey", ComCode.JFEN_MERCHANT_KEY);
        dto.put("timestamp", System.currentTimeMillis());
        dto.put("passwd", request.getPasswd());
        dto.put("productName", "productName");
        dto.put("tradeNo", orderEntity.getTradeNo());

        dto.put("swpaccid", cardEntity.getSwpaccid());

        JSONObject jsonObject = juHeZhongPayJFenService.openCard(dto);


        payBackDto.setMessage(jsonObject.getString("msg"));
        if ("0000".equals(jsonObject.get("code"))) {

//            this.notifyPay(orderEntity);
            return payBackDto;
        } else {
            throw new MyException(jsonObject.getString("msg"));
        }

    }


    // HL4 通道
    @Transactional(readOnly = false)
    public PayBackDto payJuhezhong(JuHeZhongPayRequest request, UserEntity userEntity, OrderEntity orderEntity, CardEntity cardEntity) throws Exception {

        //获取用户对应等级费率以及每笔需要的手续费
        RateEntity gradeRate = getGradeRate(userEntity.getLevel(), request.getPayChannel());
        logger.debug("用户等级请求结果，费率: {}, 单笔价格: {}", gradeRate.getRate(), gradeRate.getSiglePrice());
        //获取扣除手续费后的金额,已经转换为分
//        BigDecimal amount = calculationAmount(gradeRate, request.getAmount());
//        int amountFen = amount.multiply(BigDecimal.valueOf(100.0)).setScale(2, BigDecimal.ROUND_HALF_UP).intValue();
        int amount = calculationAmount(gradeRate, request.getAmount());
        //通过用户code获取user_detail表中数据
        UserDetailEntity userDetail = userService.getUserDetailByCode(userEntity.getCode());
        PayBackDto payBackDto = new PayBackDto();
        payBackDto.setIsUrl("0");
        //获取结算卡信息
        CardEntity cardEntityDebit = userService.getCardInfoByCode(userEntity);
        JuhezhongDto dto = new JuhezhongDto();
        dto.setOrderId(orderEntity.getPayCode());//非订单号，回调根据此值进行修改
        dto.setMerchantId(ComCode.MERCHANT_ID);//商户号
        dto.setMerchantKey(ComCode.MERCHANT_KEY);
        dto.setAmount(Integer.valueOf(request.getAmount()) * 100);//订单金额,单位为分
        dto.setTrxType(3);//交易类型，默认传3
        dto.setType(cardEntity.getCardType().equals("D") ? 6 : 5);//5 借记卡 只能 D0 6 贷记卡 D0 t1 ,表中 银行卡类型 D储蓄卡 C信用卡'
        dto.setBankNo(cardEntity.getCardNo());//支付卡号
        dto.setCvn2(cardEntity.getCvn2());//安全码
        dto.setPhone(cardEntity.getCardMobile());//支付卡预留手机号
        dto.setExpired(cardEntity.getExpireDate());//信用卡有效期(MMYY)

        dto.setUserFee(amount < 200 ? Integer.valueOf(ComCode.EXTRA_RATE) : amount);//手续费 单位：分 ，D0 业务必传,商家约定
        if (cardEntity.getCardType().equals("C")) {
            if (cardEntityDebit == null) {
                throw new MyException("还没有结算卡！");
            }
            dto.setSettleBankName(cardEntityDebit.getBankName());//结算银行 D0 业务必传
            dto.setSettleBankNo(cardEntityDebit.getCardNo());//一个身份证只能对应一个结算卡 D0 业务必传
            dto.setSettleBankPhone(cardEntityDebit.getCardMobile());//结算卡预留手机号 D0 业务必传
            dto.setName(userDetail.getRealName());//开户名 D0 业务必传
            dto.setCertificateCode(userDetail.getIdCard());//开户人身份证号 D0 业务必传
        }
        dto.setNotifyUrl(ComCode.NOTIFY_CALLBACK_URL);//通知url
        dto.setFrontUrl(ComCode.NOTIFY_CALLBACK_URL);//前台地址url(保留)
        dto.setTimestamp(System.currentTimeMillis());
        logger.debug("HL4支付请求参数， expireDate: {}, cvn2: {}, cardMobile: {}, " +
                        "cardNo: {}, settleBankName: {}, settleBankNo: {}, settleBankPhone:{}, " +
                        "name:{}, certificateCode:{}, userFee:{}", request.getExpireDate(), request.getCvn2(),
                cardEntity.getCardMobile(), cardEntity.getCardNo(), cardEntityDebit.getBankName(), cardEntityDebit.getCardNo(),
                cardEntityDebit.getCardMobile(), userDetail.getRealName(), userDetail.getIdCard(), amount);

        JSONObject jsonObject = juHeZhongPayService.quickPay(dto);
        logger.debug("HL4支付返回结果信息:{}" + jsonObject.toJSONString());
        payBackDto.setMessage(jsonObject.getString("msg"));
        if ("0000".equals(jsonObject.get("code"))) {
            //订单支付成功，则进行一次查询，修改订单状态
//            this.notifyPay(orderEntity);
            return payBackDto;
        } else {
            throw new MyException(jsonObject.getString("msg"));
        }

    }

    /**
     * huanqiuhuiju 快捷支付
     *
     * @param request
     * @return
     */
    public PayBackDto huanqiuhujuPay(UserEntity userEntity, OrderEntity orderEntity, JuHeZhongPayRequest request, CardEntity cardEntity) throws Exception {
        PayBackDto payBackDto = new PayBackDto();
        JSONObject dto = new JSONObject();
        String orderId = IdGen.randomBase62(32);
        RateEntity rateEntity = new RateEntity();
        rateEntity.setUserLevel(userEntity.getLevel());
        rateEntity.setPayMethod("quick");
        rateEntity.setPayChannel(ComCode.PAYCHANNEL_HUANQIUHUIJU);
        rateEntity = userService.getRateByLevel(rateEntity);

        dto.put("transcode", "300");// 交易码
        dto.put("version", "0100"); // 版本号
        dto.put("ordersn", MakeOrderNum.makeOrderNum()); // 流水号 每次交易都唯一
        dto.put("merchno", ComCode.HUANQIUHUIJU_MERCHANT_ID); // 商户号
        dto.put("dsorderid", orderId); // 订单号 唯一
        dto.put("txnAmt", request.getAmount()); // 交易金额
        dto.put("txnRate", String.valueOf(Double.valueOf(rateEntity.getRate()) * 100));// 费率

        dto.put("siglePrice", rateEntity.getSiglePrice()); // 单笔价格
        dto.put("merchno", ComCode.HUANQIUHUIJU_MERCHANT_ID); // 商户号
        dto.put("realName", userEntity.getUserDetail().getRealName()); // 真实姓名
        dto.put("idCardNo", userEntity.getUserDetail().getIdCard()); // 身份证号
        dto.put("bankCardNo", cardEntity.getCardNo());// 银行卡号
        dto.put("bankCode", cardEntity.getBelongBank()); // 银行代码
        dto.put("bankName", cardEntity.getBankName()); // 消费卡银行名称
        dto.put("phone", cardEntity.getCardMobile()); // 手机号
        dto.put("cvn2", request.getCvn2());
        dto.put("expireDate", request.getExpireDate());
        dto.put("notifyUrl", Global.getConfig("project.access.url") + "/api/pay/notifyHuanqiuhuijuPay");
        dto.put("settleBankCode", userEntity.getUserDetail().getCard().getBelongBank()); // 结算银行代码
        dto.put("settleCardNo", userEntity.getUserDetail().getCard().getCardNo()); // 结算银行卡
        dto.put("settlePhone", userEntity.getUserDetail().getCard().getCardMobile()); // 结算手机号
        dto.put("settleCardBankName", userEntity.getUserDetail().getCard().getBankName()); // 结算卡银行名称
        System.out.println(dto.toJSONString());
        JSONObject jsonObject = huanqiuhuijuService.huanqiuhuijuPay(dto);

        if ("0000".equals(jsonObject.get("returncode"))) {
            payBackDto.setIsUrl("0");
            payBackDto.setPayChannel(ComCode.PAYCHANNEL_HUANQIUHUIJU);
//            this.notifyPay(orderEntity);
            return payBackDto;
        } else {
            orderFail(orderEntity);
            throw new MyException(jsonObject.getString("errtext"));
        }

    }


    /**
     * 支付宝支付
     *
     * @param request
     * @return
     * @throws AlipayApiException
     */
    @Transactional(readOnly = false)
    public PayBackDto aliPay(JuHeZhongPayRequest request) throws AlipayApiException {
        // 1. 根据入参获取用户详情信息，包括支付卡片信息
        UserEntity userEntity = userService.getUserInfo(new Request(request.getSubMerchantCode()));
        userEntity = userService.getUserDetailInfo(userEntity);

        // 2. 创建支付订单信息，并保存
        String code = IdGen.randomBase62(64);
        String payNo = ComCode.YYYYMMDDHHMM.format(new Date()) + IdGen.randomBase62(8); // 订单号
        String payCode = IdGen.randomBase62(64);
        DecimalFormat df = new DecimalFormat("######0.00");
        List<Dict> list = DictUtils.getDictList("level_" + request.getLevel());
        String amount = "398";
        if (list != null && list.size() > 0) {
            amount = list.get(0).getValue();
        }
        logger.debug("支付宝支付金额: {}", amount);
        // 创建订单保存
        if ("D".equals(request.getLevel())) {
            request.setSubject("升级成白银会员");
        } else if ("C".equals(request.getLevel())) {
            request.setSubject("升级成黄金会员");
        } else if ("B".equals(request.getLevel())) {
            request.setSubject("升级成钻石会员");
        }
        OrderEntity orderEntity = new OrderEntity(code, request.getSubMerchantCode(), payNo, payCode, request.getPayMethod(), "ali", "1", amount, request.getLevel() + ":" + request.getSubject(), "", "0", request.getCardCode());
        payDao.saveOrderInfo(orderEntity);

        if ("B".equals(request.getLevel())) {
            UpgradeUserEntity upgradeUserEntity = new UpgradeUserEntity();
            upgradeUserEntity.setUserCode(request.getSubMerchantCode());
            upgradeUserEntity.setLevel(request.getLevel());
            upgradeUserEntity.setOrderCode(payCode);
            upgradeUserEntity.setStatus("0");
            upgradeUserEntity.setAfterMobile(request.getAfterMobile());
            userService.addUpgradeUser(upgradeUserEntity);
        }


        // 支付宝支付返回对应支付信息
        JSONObject dto = new JSONObject();
        dto.put("payCode", payCode);
        dto.put("subject", request.getSubject());
        dto.put("amount", amount);
        dto.put("body", new HashMap<>());

        String body = alipayService.aliPay(dto);
        PayBackDto payBackDto = new PayBackDto();
        payBackDto.setBody(body);
        return payBackDto;
    }


    /**
     * 提现
     *
     * @param request
     * @return
     * @throws AlipayApiException
     */
    @Transactional(readOnly = false)
    public Response putForward(JuHeZhongPayRequest request) throws Exception {
        Response response = new Response();
        BenefitEntity entity = new BenefitEntity();
        entity.setUserCode(request.getSubMerchantCode());
        BalanceEntity balanceEntity = benefitSevice.getBalanceM(entity);

        if (balanceEntity != null && StringUtils.isNotBlank(balanceEntity.getBalance()) && Double.valueOf(balanceEntity.getBalance()) >= Double.valueOf(request.getAmount())) {
            // 1. 根据入参获取用户详情信息，包括支付卡片信息
            UserEntity userEntity = userService.getUserInfo(new Request(request.getSubMerchantCode()));
            userEntity = userService.getUserDetailInfo(userEntity);

            CardEntity cardEntity = userService.getCardInfo(request);

            // 2. 创建支付订单信息，并保存
            String code = IdGen.randomBase62(64);
            String payNo = ComCode.YYYYMMDDHHMM.format(new Date()) + IdGen.randomBase62(8); // 订单号
            String payCode = IdGen.randomBase62(20);

            OrderEntity orderEntity = new OrderEntity(code, request.getSubMerchantCode(), payNo, payCode, ComCode.PAYMETHOD_PUTFORWARD, ComCode.PAYMETHOD_PUTFORWARD, "1", request.getAmount(), "提现", "", "0", request.getCardCode());
            payDao.saveOrderInfo(orderEntity);

            // 添加提现记录
            String benefitCode = IdGen.randomBase62(64);
            BenefitEntity benefitEntity = new BenefitEntity(benefitCode, request.getSubMerchantCode(), payCode, orderEntity.getPayChannel(), "2", "M", orderEntity.getAmount(), orderEntity.getCardCode());
//                        benefitEntity.setAmount(String.valueOf(Double.valueOf(benefitEntity.getAmount())));
            benefitEntity.setPayMethod(orderEntity.getPayMethod());
            payDao.saveBenefitInfo(benefitEntity);

            // 平安银行转账
            PingAnBankDto dto = new PingAnBankDto();
            dto.setOrderCode(payCode);
            dto.setEnterprisecode(ComCode.PINGANBANK_ENTERPRISECODE);
//        dto.setEnterprisecode("00103082100008003000");
            JSONObject jsonObject = new JSONObject();

            jsonObject.put("ThirdVoucher", payCode); // 转账凭证号 标示交易唯一性，同一客户上送的不可重复，建议格式：yyyymmddHHSS+8位系列
            jsonObject.put("CcyCode", "RMB"); // 货币类型 RMB-人民币
            jsonObject.put("OutAcctNo", ComCode.PINGANBANK_OUTACCTNO); // 付款人账户 扣款账户
            jsonObject.put("OutAcctName", ComCode.PINGANBANK_OUTACCTNAME); // 付款人名称 付款账户户名
            jsonObject.put("OutAcctAddr", "34343"); // 付款人地址 建议填写付款账户的分行、网点名称  非必输
            jsonObject.put("InAcctBankNode", cardEntity.getBelongBank()); // 收款人开户行行号 跨行转账建议必输。为人行登记在册的商业银行号

            jsonObject.put("InAcctNo", cardEntity.getCardNo()); // 收款人账户
            jsonObject.put("InAcctName", userEntity.getUserDetail().getRealName()); // 收款人账户户名

            jsonObject.put("InAcctBankName", cardEntity.getBankName()); // 收款人开户行名称
            jsonObject.put("TranAmount", request.getAmount()); // 转出金额 如为XML报文，则直接输入输出以元为单位的浮点数值，如2.50 (两元五角)
            jsonObject.put("UseEx", "ZZZZZtestreturn"); // 资金用途 30个汉字。现金管理代理结算 非必输
            jsonObject.put("UnionFlag", cardEntity.getBelongBank().equals(ComCode.PINGANBANK_OUTACCTBANK) ? 1 : 0); // 行内跨行标志 1：行内转账，0：跨行转账
            jsonObject.put("SysFlag", "1"); // Y：加急 N：普通S：特急默认为N
            jsonObject.put("AddrFlag", "1"); // 同城/异地标志 “1”—同城   “2”—异地；若无法区分，可默认送1-同城。

            JSONObject result = pingAnBankService.singleTransfer(dto, jsonObject);

            if (result.get("all") != null) {

                String str = result.getString("all");
                String reg = "[^\u4e00-\u9fa5]";
                str = str.replaceAll(reg, " ");
                str = str.trim();
                System.out.println(str);
                response.setMessage(str);
                response.setStatus(ComCode.STATUS_CODE_9998);
                return response;

            }
//        response.setMessage(str);
            response.setStatus(ComCode.STATUS_CODE_2000);
            return response;
        }

        response.setStatus(ComCode.STATUS_CODE_9998);
        response.setMessage("余额不足");
        return response;


    }


    /**
     * 回调
     *
     * @param orderEntity
     * @return
     * @throws Exception
     */
    @Transactional(readOnly = false)
    public OrderEntity notifyPay(OrderEntity orderEntity) throws Exception {
        //当出现收不到回调，会有定时任务进行查询，修改订单状态，因此不立即进行查询操作，立即查询会出现操作频繁
//        QuickDto dto = new QuickDto();
//        dto.setOrderId(orderEntity.getPayCode());
//        dto.setMerchantId(ComCode.MERCHANT_ID);
//        dto.setMerchantKey(ComCode.MERCHANT_KEY);
//        dto.setTimestamp(System.currentTimeMillis());
//
        orderEntity = payDao.getOrder(orderEntity);
//        JSONObject jsonObject = null;
//        if (ComCode.PAYCHANNEL_HL3.equals(orderEntity.getPayChannel())) {
//            dto.setMerchantId(ComCode.INTEGRAL_MERCHANT_ID);
//            dto.setMerchantKey(ComCode.INTEGRAL_MERCHANT_KEY);
//            jsonObject = juHeZhongPayIntegralService.query(dto);
//        } else if (ComCode.PAYCHANNEL_HL1.equals(orderEntity.getPayChannel())) {
//            jsonObject = juHeZhongPayService.query(dto);
//        } else if (ComCode.PAYCHANNEL_HL2.equals(orderEntity.getPayChannel())) {
//            dto.setMerchantId(ComCode.JFEN_MERCHANT_ID);
//            dto.setMerchantKey(ComCode.JFEN_MERCHANT_KEY);
//            jsonObject = juHeZhongPayJFenService.query(dto);
//        } else if (ComCode.PAYCHANNEL_HUANQIUHUIJU.equals(orderEntity.getPayChannel())) {
//            orderEntity.setPayStatus("2");
//            payDao.updateOrderStatus(orderEntity);
//            return orderEntity;
//        }
//
//        logger.debug("查询订单返回结果: {}" + jsonObject.toJSONString());
        // 支付成功
        //订单已经支付成功，则不进行再次修改，可能存在多次回调，所以进行判断
        if (!orderEntity.getPayStatus().equals("2")) {
            logger.debug("进入修改订单状态");
            orderEntity.setPayStatus("2");
            payDao.updateOrderStatus(orderEntity);
        }
        orderEntity = payDao.getOrder(orderEntity);
        return orderEntity;
    }


    /**
     * 回调
     *
     * @param orderEntity
     * @return
     * @throws Exception
     */
    @Transactional(readOnly = false)
    public OrderEntity aliPayNotifyPay(OrderEntity orderEntity, String code) throws Exception {

        if ("TRADE_SUCCESS".equals(code)) {

            orderEntity.setPayStatus("2");
            payDao.updateOrderStatus(orderEntity);
            orderEntity = payDao.getOrder(orderEntity);

            UserEntity userEntity = new UserEntity();
            userEntity.setCode(orderEntity.getUserCode());

            if (orderEntity.getSubject() != null && !"".equals(orderEntity.getSubject())) {
                userEntity.setLevel(orderEntity.getSubject().substring(0, 1));

                if ("B".equals(userEntity.getLevel())) {
                    UpgradeUserEntity upgradeUserEntity = new UpgradeUserEntity();
                    upgradeUserEntity.setUserCode(orderEntity.getUserCode());
                    upgradeUserEntity.setLevel(userEntity.getLevel());
                    upgradeUserEntity.setStatus("1");
                    upgradeUserEntity.setOrderCode(orderEntity.getPayCode());
                    userService.updateUpgradeUser(upgradeUserEntity);
                }
//                else {
//                    //支付宝升级成功后，对应的HL2通道需要修改费率
//                    userService.updateUserLevelByCode(userEntity);
//                    UserSubMchId userSubMchId = new UserSubMchId();
//                    userSubMchId.setUserCode(orderEntity.getUserCode());
//                    userSubMchId.setPayChannel("quick_jfen");
//                    UserSubMchId userSubMchIdQuery = userDao.getUserSubmchid(userSubMchId);
//                    if (userSubMchIdQuery != null){
//                        logger.debug("支付宝升级后，开始进行修改HL2费率");
//                        //修改费率
//                        RateEntity rateEntity = new RateEntity();
//                        rateEntity.setPayChannel("quick_jfen");
//                        rateEntity.setPayMethod("quick");
//                        rateEntity.setUserLevel(userEntity.getLevel());
//                        RateEntity rateByLevel = userDao.getRateByLevel(rateEntity);
//                        rateByLevel.setServiceType("1");//修改的标识
//                        userService.merchantFeelJFen(userSubMchIdQuery.getSubmchid(),rateByLevel);
//                    }
//                }
            }
        } else {
            orderEntity.setPayStatus("4");
            payDao.updateOrderStatus(orderEntity);
            orderEntity = payDao.getOrder(orderEntity);

            if (orderEntity.getSubject() != null && !"".equals(orderEntity.getSubject()) && "A".equals(orderEntity.getSubject().substring(0, 1))) {
                UpgradeUserEntity upgradeUserEntity = new UpgradeUserEntity();
                upgradeUserEntity.setUserCode(orderEntity.getUserCode());
                upgradeUserEntity.setLevel(orderEntity.getSubject().substring(0, 1));
                upgradeUserEntity.setOrderCode(orderEntity.getPayCode());
                upgradeUserEntity.setStatus("3");
                userService.updateUpgradeUser(upgradeUserEntity);
            }
        }
        return orderEntity;
    }


    public OrderEntity getOrder(OrderEntity orderEntity) {
        return payDao.getOrder(orderEntity);
    }

    public OrderEntity getOrder(String payNo) {
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setPayNo(payNo);
        return payDao.getOrder(orderEntity);
    }

    /**
     * 交易超过7天则修改为交易失败
     */
    @Transactional(readOnly = false)
    public void updateOrderTiming() {
//        System.out.println("。。。。。。。定时任务。updateOrderTiming开始。。。。");
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setEndTime(DateUtils.getDateByDay("yyyy-MM-dd HH:mm:ss", -7));
        List<OrderEntity> list = payDao.getOrderListTimeing(orderEntity);
        for (OrderEntity order : list) {
            order.setPayStatus("3");
            payDao.updateOrderStatus(order);
            BenefitEntity benefitEntity = new BenefitEntity();
            benefitEntity.setOrderCode(order.getPayCode());
            payDao.deleteBenefit(benefitEntity);
        }
//        System.out.println("。。。。。。。定时任务。updateOrderTiming结束。。。。");
    }

    /*
    *  查询交易的状态并修改
     */
    @Transactional(readOnly = false)
    public void updateOrders() {
//        System.out.println("。。。。。。。定时任务。updateOrders开始。。。。");
        try {
            OrderEntity orderEntity = new OrderEntity();
            orderEntity.setStartTime(DateUtils.getDateByDay("yyyy-MM-dd HH:mm:ss", -7));
            orderEntity.setEndTime(DateUtils.formatDate(DateUtils.addHours(new Date(), -12), "yyyy-MM-dd HH:mm:ss"));
            List<OrderEntity> list = payDao.getOrderListTimeing(orderEntity);
            for (OrderEntity order : list) {

                // 快捷支付
                if ("quick".equals(order.getPayMethod())) {
                    QuickDto dto = new QuickDto();
                    dto.setOrderId(order.getPayCode());

                    dto.setTimestamp(System.currentTimeMillis());
                    JSONObject jsonObject = null;
                    if (ComCode.PAYCHANNEL_HL3.equals(order.getPayChannel())) {
                        dto.setMerchantId(ComCode.MERCHANT_ID);
                        dto.setMerchantKey(ComCode.MERCHANT_KEY);

                        jsonObject = juHeZhongPayIntegralService.query(dto);

                    } else if (ComCode.PAYCHANNEL_HL1.equals(order.getPayChannel())) {
                        jsonObject = juHeZhongPayService.query(dto);
                    } else if (ComCode.PAYCHANNEL_HL2.equals(orderEntity.getPayChannel())) {
                        dto.setMerchantId(ComCode.JFEN_MERCHANT_ID);
                        dto.setMerchantKey(ComCode.JFEN_MERCHANT_KEY);
                        jsonObject = juHeZhongPayJFenService.query(dto);
                    }
                    if (jsonObject != null) {
//                    System.out.println("查询订单返回结果："+jsonObject.toJSONString());
                        // 支付成功
                        if ("0000".equals(jsonObject.get("code"))) {
                            System.out.println("定时任务查询订单返回结果：" + jsonObject.toJSONString());
                            order.setPayStatus("2");
                            payDao.updateOrderStatus(order);
                        } else { // 支付失败
                            orderFail(order);
                        }
                    }
                } else if ("put_forward".equals(order.getPayMethod())) { // 提现
                    // 查询单笔转账

                    PingAnBankDto dto = new PingAnBankDto();
                    dto.setOrderCode(IdGen.randomBase62(20));
                    dto.setEnterprisecode(ComCode.PINGANBANK_ENTERPRISECODE);
                    JSONObject jsonObject = new JSONObject();


                    jsonObject.put("OrigThirdVoucher", order.getPayCode()); // 转账凭证号 推荐使用；使用4004接口上送的ThirdVoucher或者4014上送的SThirdVoucher

                    JSONObject jsonObject1 = pingAnBankService.querySingleTransfer(dto, jsonObject);
                    if ("20".equals(jsonObject1.getString("Stt"))) {// 交易成功
                        order.setPayStatus("2");
                        payDao.updateOrderStatus(order);

                        BenefitEntity benefitEntity = new BenefitEntity();
                        benefitEntity.setOrderCode(order.getPayCode());
                        benefitEntity.setDelFlag("1");
                        payDao.deleteBenefit(benefitEntity);
                    }
                }


            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    public JSONObject queryForward(String payCode) throws Exception {
        // 查询单笔转账

        PingAnBankDto dto = new PingAnBankDto();
        dto.setOrderCode(payCode);
        dto.setEnterprisecode(ComCode.PINGANBANK_ENTERPRISECODE);
        JSONObject jsonObject = new JSONObject();


        jsonObject.put("OrigThirdVoucher", payCode); // 转账凭证号 推荐使用；使用4004接口上送的ThirdVoucher或者4014上送的SThirdVoucher

        JSONObject jsonObject1 = pingAnBankService.querySingleTransfer(dto, jsonObject);

        return jsonObject1;
    }

    public BalanceEntity getPutForwardNum(JuHeZhongPayRequest request) {
        BenefitEntity entity = new BenefitEntity();
        entity.setUserCode(request.getSubMerchantCode());
        BalanceEntity balanceEntity = benefitSevice.getBalanceM(entity);
        return balanceEntity;
    }

    public BalanceEntity getPutForwardNumHighLevel(JuHeZhongPayRequest request) {
        BalanceEntity balanceEntity = new BalanceEntity();
        BenefitEntity entity = new BenefitEntity();
        entity.setUserCode(request.getSubMerchantCode());
        UserEntity userInfo = userService.getUserInfo(request);
        //高级别用户
        //是否已经有推荐的用户
        UserEntity recomUserEntity = benefitSevice.checkRecommend(userInfo.getMobile());
        //升级前用户
        UserEntity upgradeUserInfo = userDao.getUpgradeUserInfo(userInfo.getMobile());
        if (recomUserEntity == null) {
            balanceEntity.setBalance("0.00");
            return balanceEntity;
        }
        String levelRate = benefitSevice.getRateByLevel(userInfo.getLevel());
        // 总收益
        entity.setUserCode(request.getSubMerchantCode());
        entity.setBenefitType(levelRate);
        entity.setCreateDate(userInfo.getCreated());
        entity.setCardCode(upgradeUserInfo.getMobile());
        BenefitEntity benefitEntityA = payDao.getBenefitSumHighLevel(entity);

        // 总提现
        BenefitEntity benefitEntityM = payDao.getBenefitSumHighLevelM(entity);

        // 余额 = 总收益-总提现
        balanceEntity = benefitSevice.getLastBalance(benefitEntityA, benefitEntityM);

        return balanceEntity;
    }

    private void orderFail(OrderEntity orderEntity) {
        orderEntity.setPayStatus("4");
        payDao.updateOrderStatus(orderEntity);
        BenefitEntity benefitEntity = new BenefitEntity();
        benefitEntity.setOrderCode(orderEntity.getPayCode());
        benefitEntity.setDelFlag("1");
        payDao.deleteBenefit(benefitEntity);
    }

    /**
     * 获取对应用户等级的费率
     *
     * @param user_level
     * @param pay_channel
     * @return
     */
    public RateEntity getGradeRate(String user_level, String pay_channel) {
        Map<String, String> maps = Maps.newHashMap();
        maps.put("user_level", user_level);
        maps.put("pay_channel", pay_channel);
        RateEntity rateList = rateDao.getRateEntity(maps);
        return rateList;
    }


    /**
     * 获取用户当日已使用额度，已支付完成时间为准
     *
     * @param user_code
     * @param pay_channel
     * @return
     */
    public Double getUseNum(String user_code, String pay_channel) {
        HashMap<String, String> maps = Maps.newHashMap();
        maps.put("user_code", user_code);
        maps.put("pay_channel", pay_channel);
        Double lastLimit = payDao.getLastLimit(maps);
        return lastLimit;
    }

    /**
     * 计算当日剩余额度
     *
     * @param dayLimit
     * @param num
     * @return
     */
    public BigDecimal getLimitNum(String dayLimit, Double num) {
        return BigDecimal.valueOf(Long.valueOf(dayLimit)).subtract(BigDecimal.valueOf(num));
    }

    /**
     * 计算当日剩余额度（集中）
     *
     * @param user_level
     * @param user_code
     * @param pay_channel
     * @return
     */
    public BigDecimal getLimitNumber(String user_level, String user_code, String pay_channel) {
        Map<String, String> maps = Maps.newHashMap();
        maps.put("user_level", user_level);
        maps.put("pay_channel", pay_channel);
        maps.put("user_code", user_code);
        RateEntity rateList = rateDao.getRateEntity(maps);
        Double num = payDao.getLastLimit(maps);
        return BigDecimal.valueOf(Long.valueOf(rateList.getDayLimit())).subtract(BigDecimal.valueOf(num));
    }

    /**
     * 计算每笔交易手续费的和（HL4用）
     *
     * @param gradeRate
     * @param amount
     * @return
     */
    public int calculationAmount(RateEntity gradeRate, String amount) {
        Double siglePrice = Double.valueOf(gradeRate.getSiglePrice());
        Double rate = Double.valueOf(gradeRate.getRate());
        Double amountDouble = Double.valueOf(amount);
        //总共所需手续费
        int result = BigDecimal.valueOf(amountDouble * rate).add(BigDecimal.valueOf(siglePrice).subtract(BigDecimal.ONE)).multiply(BigDecimal.valueOf(100)).intValue();
        logger.debug("计算出来的费率：" + result);
        //扣除费率及手续费后的金额
//        BigDecimal result = BigDecimal.valueOf(amountDouble).subtract(BigDecimal.valueOf(siglePrice))
//                .subtract(BigDecimal.valueOf(amountDouble * rate));
        return result;
    }

    /**
     * 计算每笔交易手续费的和（HL2用）
     *
     * @param gradeRate
     * @return
     */
    public int calculationAmountHL2(RateEntity gradeRate) {
        Double siglePrice = Double.valueOf(gradeRate.getSiglePrice());
        //总共所需手续费，只算每笔的手续费，单位是分
        int result = BigDecimal.valueOf(siglePrice * 100).intValue();
        return result;
    }
}
