package cn.pluss.platform.merchant.impl;

import cn.pluss.platform.activityConsumReturn.ActivityConsumReturnService;
import cn.pluss.platform.api.Result;
import cn.pluss.platform.api.ResultCode;
import cn.pluss.platform.api.ResultGenerator;
import cn.pluss.platform.constants.Constant;
import cn.pluss.platform.dto.AccountDTO;
import cn.pluss.platform.entity.*;
import cn.pluss.platform.enums.PayMessageType;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.exception.PayRiskException;
import cn.pluss.platform.fans.FansService;
import cn.pluss.platform.ipLocation.IpLocationService;
import cn.pluss.platform.leshua.LeshuaSignature;
import cn.pluss.platform.mapper.*;
import cn.pluss.platform.memberOrder.MemberOrderService;
import cn.pluss.platform.mercOrderToken.MercOrderTokenService;
import cn.pluss.platform.merchant.AccountService;
import cn.pluss.platform.merchant.MerchantCashPlaceService;
import cn.pluss.platform.merchant.MerchantRateNewService;
import cn.pluss.platform.merchant.MerchantService;
import cn.pluss.platform.merchant.MerchantBaseInfoService;
import cn.pluss.platform.merchantChannelStatus.MerchantChannelStatusService;
import cn.pluss.platform.merchantMenber.MerchantMenberService;
import cn.pluss.platform.merchantMenberComsume.MerchantMenberComsumeService;
import cn.pluss.platform.merchantMenberRecharge.MerchantMenberRechargeService;
import cn.pluss.platform.merchantOrder.MerchantOrderService;
import cn.pluss.platform.merchantProfit.MerchantProfitService;
import cn.pluss.platform.merchantStore.MerchantStoreService;
import cn.pluss.platform.mswitch.CommonSwitchService;
import cn.pluss.platform.notify.NotifyMessageService;
import cn.pluss.platform.pay.PayService;
import cn.pluss.platform.ryx.pay.RyxPayService;
import cn.pluss.platform.sxf.pay.SxfPayService;
import cn.pluss.platform.user.UserVoiceService;
import cn.pluss.platform.user.impl.GeneralPushUtil;
import cn.pluss.platform.userApp.UserAppService;
import cn.pluss.platform.util.*;
import cn.pluss.platform.wap.LevelDTO;
import cn.pluss.platform.wap.XmlUtil;
import cn.pluss.platform.wechat.WxConstants;
import cn.pluss.platform.wx.WxAccessTokenRequest;
import cn.pluss.platform.wx.WxCommonService;
import cn.pluss.platform.wx.WxOauth2AccessTokenResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.aliyuncs.geoip.model.v20200101.DescribeIpv4LocationResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.FastDateFormat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.*;

@Slf4j
@Service
@RequiredArgsConstructor
public class MerchantServiceImpl implements MerchantService {

    @Autowired
    private GeneralPushUtil generalPushUtil;

    private final MerchantOrderMapper merchantOrderMapper;

    private final MerchantBaseInfoService merchantBaseInfoService;

    private final FansService fansService;

    private final MerchantProfitService merchantProfitService;

    private final MemberOrderService memberOrderService;

    private final MerchantMenberRechargeService merchantMenberRechargeService;

    private final MerchantMenberService merchantMenberService;

    private final ActivityConsumReturnService activityConsumReturnService;

    private final MerchantStoreService merchantStoreService;

    private final MerchantMenberComsumeService merchantMenberComsumeService;

    @Setter(onMethod_ = {@Autowired})
    private UserAppService userAppService;

    private final MerchantOrderService merchantOrderService;

    private final SxfPayService sxfPayService;

    @Setter(onMethod_ = {@Autowired, @Lazy})
    private MerchantChannelStatusService merchantChannelStatusService;

    @Setter(onMethod_ = {@Autowired, @Lazy})
    private AccountService accountService;

    private final NotifyMessageService notifyMessageService;

    @Qualifier("ipLocationService")
    private final IpLocationService ipLocationService;

    private final RyxPayService ryxPayService;

    private final MerchantMoveSettingMapper merchantMoveSettingMapper;

    private final MerchantMoveRecordsMapper merchantMoveRecordsMapper;

    @Setter(onMethod_ = {@Autowired, @Qualifier("ysPayOldService")})
    private PayService ysPayOldService;

    @Setter(onMethod_ = {@Autowired, @Lazy})
    private MerchantRateNewService merchantRateNewService;

    @Setter(onMethod_ = {@Autowired, @Lazy})
    private MerchantCashPlaceService merchantCashPlaceService;

    @Setter(onMethod_ = {@Autowired, @Lazy})
    private WxCommonService wxCommonService;

    @Setter(onMethod_ = {@Autowired, @Lazy})
    private CommonSwitchService commonSwitchService;

    @Setter(onMethod_ = {@Autowired, @Lazy})
    private MercOrderTokenService mercOrderTokenService;

    @Setter(onMethod_ = {@Autowired, @Lazy})
    private UserVoiceService userVoiceService;


    @Override
    public String appRefundCallback(HttpServletRequest request) {
        log.info("=========================jinruleshua huidiao =====================");
        String respString = "";
        InputStream is;
        Map<String, Object> notifyMap;
        try {
            is = request.getInputStream();
            String xml = XmlUtil.toUTF8(is);
            log.info("=========fanhui     canshu=============" + xml);
            notifyMap = XmlUtil.toMapLeshua(xml);
            log.info("==================fanhuicanshu    Map   jihe=====" + notifyMap + "");
            if (notifyMap.containsKey("sign")) {
                if (!LeshuaSignature.checkIsSignValidFromResponseString(xml, resExcludedSignParams(), "75C27ABB12F78A747DCB4368EEBCB542")) {
                    log.info("============================qianming butongguo======================");
                    respString = "error";
                } else {
                    String status = (String) notifyMap.get("status");
                    String refundMoney = notifyMap.get("refund_amount").toString();
                    log.info("============订单状态 status============" + status);
                    respString = "000000";
                    String orderNumber = (String) notifyMap.get("third_order_id");// 商户订单号

                    /* 此处查询的是已退款订单，故无需获取取消时间 */
                    MerchantOrder merchantOrder = new MerchantOrder().setOrderNumber(orderNumber).setStatus("2");
                    List<MerchantOrder> queryMerchantOrderList = merchantOrderMapper.selectList(new QueryWrapper<>(merchantOrder));
                    MerchantBaseInfo merchantBaseInfo = new MerchantBaseInfo();
                    System.out.println("======查询订单=====order=" + JSONObject.toJSONString(queryMerchantOrderList));


                    if (StringUtils.isNotEmpty(orderNumber) && queryMerchantOrderList != null && queryMerchantOrderList.size() > 0) {

                        System.out.println("======订单状态=====order=" + JSONObject.toJSONString(queryMerchantOrderList));
                        merchantOrder = queryMerchantOrderList.get(0);
                        merchantOrder.setUpdateTime(DateUtils.parse(notifyMap.get("refund_time").toString(), "yyyy-MM-dd HH:mm:ss"));
                        merchantBaseInfo.setMerchantCode(merchantOrder.getMerchantCode());
                        merchantBaseInfo = merchantBaseInfoService.queryMerchantBaseInfo(merchantBaseInfo);

                        List<String> alias = new ArrayList<>();
                        alias.add(merchantBaseInfo.getUserId());

                        String message = String.format("订单%s成功退款%s元", orderNumber, refundMoney);

                        if ("10".equals(status)) {
                            //退款中
                            merchantOrder.setStatus("4");
                        } else if ("11".equals(status)) {
                            merchantOrder.setStatus("2");
                        } else if ("12".equals(status)) {
                            generalPushUtil.sendAllPlatByAlias(alias, "支付宝进件通知", "退款失败", "1");
//                            JpushClientUtil.sendToRegistrationId2(alias, "退款通知", "退款通知", "退款失败", "1", new Date().toString());
                            merchantOrder.setStatus("3");
                        }
                        // 保存记录时间
                        if (notifyMap.get("refund_time") != null) {
                            Date date = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss", Locale.CHINA).parse(notifyMap.get("refund_time").toString());
                            merchantOrder.setUpdateTime(date);
                        } else {
                            merchantOrder.setUpdateTime(new Date());
                        }
                        merchantOrderMapper.updateById(merchantOrder);

                        System.out.println("===========开始删除粉丝消费");
                        Fans fans = new Fans();
                        fans.setOrderNumber(orderNumber);
                        List<Fans> fansList = fansService.queryFansList(fans);
                        System.out.println("===========查询粉丝消费==" + JSONObject.toJSONString(fansList));
                        for (Fans f : fansList) {
                            String userId = f.getUserId();
                            fansService.deleteFans(f);
                            System.out.println("===========删除粉丝消费==");
                            Fans queryLastFansByUserId = fansService.queryLastFansByUserId(userId);
                            if (queryLastFansByUserId != null) {
                                queryLastFansByUserId.setConsumTime(DateUtils.getEndDayOfYesterDay());
                                fansService.updateFans(queryLastFansByUserId);
                            }
                        }


                        System.out.println("===========开始删除分润记录==000000");
                        MerchantProfit merchantProfit = new MerchantProfit();
                        merchantProfit.setOrderNumber(orderNumber);
                        List<MerchantProfit> profitList = merchantProfitService.queryMerchantProfitList(merchantProfit);
                        System.out.println("===========润记录条数==000000===========size====" + profitList.size());
                        for (MerchantProfit profit : profitList) {
                            System.out.println("===========删除分润记录==000000======" + JSONObject.toJSONString(profit));
                            merchantProfitService.deleteMerchantProfit(profit);

                        }
                        System.out.println("===========成功删除分润记录==000000");


                        MemberOrder memberOrder = new MemberOrder();
                        memberOrder.setOrderNumber(orderNumber);
                        List<MemberOrder> memberOrderList = memberOrderService.queryMemberOrderList(memberOrder);
                        if (memberOrderList != null && memberOrderList.size() > 0) {

                            memberOrder = memberOrderList.get(0);
                            memberOrderService.deleteMemberOrder(memberOrder);//删除充值订单


                            MerchantMenberRecharge recharge = new MerchantMenberRecharge();
                            recharge.setOrderNumber(orderNumber);
                            List<MerchantMenberRecharge> rechargeList = merchantMenberRechargeService.queryMerchantMenberRechargeList(recharge);
                            for (MerchantMenberRecharge m : rechargeList) {
                                merchantMenberRechargeService.deleteMerchantMenberRecharge(m);
                            }
                            MerchantMenber memebr = new MerchantMenber();
                            memebr.setMemberCode(memberOrder.getMemberCode());
                            memebr = merchantMenberService.queryMerchantMenber(memebr);
                            memebr.setUsableRechargeFee(StringUtil.bigDecimal(memebr.getUsableRechargeFee() - Double.parseDouble(memberOrderList.get(0).getOrderFee())));
                            memebr.setTotalRechargeFee(StringUtil.bigDecimal(memebr.getTotalRechargeFee() - Double.parseDouble(memberOrderList.get(0).getOrderFee())));
                            merchantMenberService.updateMerchantMenber(memebr);
                        }
                        System.out.println("===========成功删除粉丝消费==000000");
                        respString = "000000";
                        return respString;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return respString;
    }

    @Override
    public void checkPayLocation(HttpServletRequest request, MerchantBaseInfo merchantBaseInfo) throws PayRiskException {
        // step 1、通过支付人的位置
        String ipAddr = IpUtils.getIpAddr(request);
        log.info("【获取用户请求IP地址】ip参数为:{}", ipAddr);
        DescribeIpv4LocationResponse clientLocation = ipLocationService.getLocation(ipAddr);
        log.info("【根据ip获取地理位置请求】返回参数:{}", JSON.toJSONString(clientLocation));
        // step 2、与商户所在位置进行对比
        if (merchantBaseInfo.getCity() == null) {
            throw new PayRiskException("商户信息不全");
        }

        if (clientLocation == null) {
            // 接口异常的情况下，暂不做这些记录
            return;
        }
//        // 付款人市信息存在，即比较市
//        if (StringUtils.isNotEmpty(clientLocation.getCity()) && !merchantBaseInfo.getCity().substring(0, 2).equals(clientLocation.getCity().substring(0, 2))) {
//            throw new PayRiskException("您当前付款距离与收款店铺过远，请当面付款！");
//        }

        //直辖市可能存在省份为空得情况
        if(StringUtil.isEmpty(merchantBaseInfo.getProvince())){
            merchantBaseInfo.setProvince(merchantBaseInfo.getCity());
        }

        // 省份未知
        if (StringUtils.isEmpty(clientLocation.getProvince())) {
            throw new PayRiskException("您当前付款距离与收款店铺过远，请当面付款！");
        }

        // 比较省份
        if (!merchantBaseInfo.getProvince().substring(0, 2).equals(clientLocation.getProvince().substring(0, 2))) {
            throw new PayRiskException("您当前付款距离与收款店铺过远，请当面付款！");
        }
    }


    @Override
    public void checkPayLocation(String ip, MerchantBaseInfo merchantBaseInfo, String province) throws PayRiskException {
        // step 1、通过支付人的位置
        log.info("【获取用户请求IP地址】ip参数为:{}", ip);
        DescribeIpv4LocationResponse clientLocation = ipLocationService.getLocation(ip);
        log.info("【根据ip获取地理位置请求】返回参数:{}", JSON.toJSONString(clientLocation));
        // step 2、与商户所在位置进行对比
        if (merchantBaseInfo.getCity() == null) {
            throw new PayRiskException("商户信息不全");
        }

        if (clientLocation == null) {
            // 接口异常的情况下，暂不做这些记录
            return;
        }

//        // 付款人市信息存在，即比较市
//        if (StringUtils.isNotEmpty(clientLocation.getCity()) && !merchantBaseInfo.getCity().substring(0, 2).equals(clientLocation.getCity().substring(0, 2))) {
//            throw new PayRiskException("您当前付款距离与收款店铺过远，请当面付款！");
//        }
        //直辖市可能存在省份为空得情况
        if(StringUtil.isEmpty(merchantBaseInfo.getProvince())){
            merchantBaseInfo.setProvince(merchantBaseInfo.getCity());
        }
        // 省份未知
        if (StringUtils.isEmpty(clientLocation.getProvince())) {
            if (StringUtils.isNotEmpty(province)) {
                if (!merchantBaseInfo.getProvince().substring(0, 2).equals(province.substring(0, 2))) {
                    throw new PayRiskException("您当前付款距离与收款店铺过远，请当面付款！");
                }
            } else {
                throw new PayRiskException("您当前付款距离与收款店铺过远，请当面付款！");
            }
        } else {
            // 比较省份
            if (!merchantBaseInfo.getProvince().substring(0, 2).equals(clientLocation.getProvince().substring(0, 2))) {
                if (StringUtils.isNotEmpty(province)) {
                    if (!merchantBaseInfo.getProvince().substring(0, 2).equals(province.substring(0, 2))) {
                        throw new PayRiskException("您当前付款距离与收款店铺过远，请当面付款！");
                    }
                } else {
                    throw new PayRiskException("您当前付款距离与收款店铺过远，请当面付款！");
                }
            }
        }
    }

    public static Set<String> resExcludedSignParams() {
        Set<String> exludedSignParams = new HashSet<>(2);
        exludedSignParams.add("sign");
        exludedSignParams.add("error_code");
        return exludedSignParams;
    }

    /**
     * 统一支付入口
     *
     * @param params
     * @return
     */
    @Override
    public Result<Map<String, Object>> tradePay(Map<String, Object> params) {
        log.info("==============>统一扫码支付下单入口，请求参数:{}<=================", params);
        //校验参数
        checkPayParams(params);
        //组装订单参数
        MerchantChannelStatus channel = (MerchantChannelStatus) params.get("channel");
        MerchantBaseInfo merchant = (MerchantBaseInfo) params.get("merchant");
        if ("1".equals(params.get("isMember")) && "memberPay".equals(params.get("radioPay"))) {
            Map<String, Object> map = toVipPay(params);
            return ResultGenerator.genSuccessResult("支付成功", map);
        }
        MerchantOrder  order = null;
        if(StringUtil.isNotEmpty(params.get("orderNumber"))){
            QueryWrapper<MerchantOrder> queryWrapper = new QueryWrapper<MerchantOrder>()
                    .eq("orderNumber",params.get("orderNumber").toString()).in("status","1","5","7");
            order = merchantOrderService.getOne(queryWrapper);
            if(order == null){
                order = getMerchantOrder(params);
            }else{
                MsgException.check("1".equals(order.getStatus()),"订单已支付，请重新生成订单支付");
                if(StringUtil.isNotEmpty(order.getMercUserId()) && StringUtil.isNotEmpty(params.get("userId"))){
                    if(!order.getMercUserId().equals(params.get("userId").toString())){
                        MsgException.throwException("当前订单已被其他付款用户绑定，请重新生成订单支付");
                    }
                }
                order.setMerchantName(merchant.getAlias());
                order.setAlias(merchant.getMerchantName());
            }
        }else{
            order = getMerchantOrder(params);
        }
       /* if("preOrder".equals(order.getDSource())){
            JSONObject resultData = new JSONObject(1);
            resultData.put("orderNumber",order.getOrderNumber());
            return ResultGenerator.genSuccessResult("处理成功", resultData);
        }*/
        JSONObject payData = null;
        if(StringUtil.isNotEmpty(order.getPayData())){
            payData = JSON.parseObject(order.getPayData());
        }else{
            JSONObject result = null;
            if (channel.getChannel() == 1) {
                result = sxfPayService.tradePay(order, channel,merchant);
            } else if (channel.getChannel() == 2) {
                MsgException.throwException("当前通道已关闭");
            } else if (channel.getChannel() == 3) {
                result = ryxPayService.tradePay(order, channel,merchant);
            } else if (channel.getChannel() == 4) {
                result = ysPayOldService.tradePay(order, channel,merchant);
            } else {
                MsgException.throwException("未知通道");
            }
            if (ResultCode.SUCCESS.code() != result.getInteger("code")) {
                return ResultGenerator.genFailResult(result.getString("msg"));
            }
            String transNo = result.getString("transNo");
            payData = result.getJSONObject("payData");
            if (StringUtils.isNotEmpty(transNo)) {
                order.setTransNo(transNo);
            }
        }
        order.setPayData(payData.toJSONString());
        if(order.getId() != null){
            merchantOrderService.updateById(order);
        }else{
            merchantOrderService.save(order);
        }
        payData.put("orderNumber", order.getOrderNumber());
        log.info("===============>组装支付参数:{}<==================", payData);
        return ResultGenerator.genSuccessResult("处理成功", payData);
    }

    /**
     * @param params:
     * @return cn.pluss.platform.api.Result<java.util.Map < java.lang.String, java.lang.Object>>
     * @description:临时码支付
     * @date: 2021/8/2 11:03
     */
    @Override
    public Result<Object> moveTradePay(Map<String, Object> params) {
        Object p = params.get("p");
        MsgException.checkNull(p, "缺失参数！");
        Object merchantCode = params.get("merchantCode");
        MsgException.checkNull(merchantCode, "缺失参数！");
        Object token = params.get("token");
        MsgException.checkNull(token, "缺失token参数！");

        Object accountName = params.get("accountName");
        MsgException.checkNull(accountName, "请输入收款方姓名！");
        Object accountPhone = params.get("accountPhone");
        MsgException.checkNull(accountPhone, "请输入收款方手机号！");

        MerchantMoveSetting setting = merchantMoveSettingMapper.selectOne(new QueryWrapper<MerchantMoveSetting>().eq("merchantCode", merchantCode));
        MsgException.checkNull(setting, "商户暂未开启动态码配置！");
        MsgException.checkNull(!"1".equals(setting.getStatus()), "商户动态码功能已关闭，请联系客服！");
        MerchantMoveRecords record = merchantMoveRecordsMapper.selectOne(new QueryWrapper<MerchantMoveRecords>().eq("merchantCode", merchantCode).eq("token", token));
        MsgException.checkNull(record, "商编和token不匹配！");
        String ip = params.get("ip").toString();
        MsgException.check(!ip.equals(record.getIp()), "当前付款用户ip不匹配！");

        //查询今天该商户支付成功次数
        String nowDate = DateUtils.formatDateDefault(new Date(), "yyyyMMdd");
        QueryWrapper<MerchantMoveRecords> queryWrapper = new QueryWrapper<MerchantMoveRecords>().eq("merchantCode", merchantCode)
                .apply("date_format(createTime, '%Y%m%d') = {0}", nowDate);
        Integer toDayCount = merchantMoveRecordsMapper.getPaySuccessCount(queryWrapper);
        if (toDayCount >= setting.getPayNum()) {
            MsgException.throwException("当天超出支付笔数上限制！");
        }
        String pStr = "";
        try {
            String pk = new String(Base64.getDecoder().decode(p.toString()), "UTF-8");
            pStr = AESEncrypt.decryptEcb(pk, setting.getAesKey());
            log.info("解析后的参数为：{}", pStr);
            if (StringUtil.isEmpty(pStr)) {
                MsgException.throwException("参数解析出错！");
            }
        } catch (RuntimeException e) {
            e.printStackTrace();
            MsgException.throwException("参数解析出错！");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            MsgException.throwException("参数解析出错！");
        }
        String time = pStr.substring(pStr.indexOf("time=") + 5);
        if (StringUtil.isEmpty(time)) {
            MsgException.throwException("缺失time参数！");
        }
        long now = System.currentTimeMillis();
        if (now > Long.valueOf(time).longValue()) {
            MsgException.throwException("支付时间已过期，请更换二维码扫码支付！");
        }
        checkPayParams(params);
        //组装订单参数
        if (pStr.indexOf("payType=") > -1) {
            int before = pStr.indexOf("payType=");
            int i = pStr.indexOf("&", before);
            String payWay = pStr.substring(before + 8, i);
            params.put("payWay", payWay);
        }
        if (pStr.indexOf("cokus=") > -1) {
            int before = pStr.indexOf("cokus=");
            int i = pStr.indexOf("&", before);
            String userId = pStr.substring(before + 6, i);
            params.put("userId", userId);
        }
        MerchantOrder order = getMerchantOrder(params);
        MerchantBaseInfo merchant = (MerchantBaseInfo) params.get("merchant");
        MerchantChannelStatus channel = (MerchantChannelStatus) params.get("channel");
        JSONObject result = null;
        if (channel.getChannel() == 1) {
            result = sxfPayService.tradePay(order, channel,merchant);
        } else if (channel.getChannel() == 2) {
            MsgException.throwException("当前通道已关闭");
        } else if (channel.getChannel() == 3) {
            result = ryxPayService.tradePay(order, channel,merchant);
        } else if (channel.getChannel() == 4) {
            result = ysPayOldService.tradePay(order, channel,merchant);
        } else {
            MsgException.throwException("未知通道");
        }
        if (ResultCode.SUCCESS.code() != result.getInteger("code")) {
            return ResultGenerator.genFailResult(result.getString("msg"));
        }
        //插入订单
        log.info("================>【支付】下单组装返回参数结果为:{}<==================", result);
        String transNo = result.getString("transNo");
        if (StringUtils.isNotEmpty(transNo)) {
            order.setTransNo(transNo);
        }
        merchantOrderService.save(order);

        record.setOrderNumber(order.getOrderNumber());
        record.setPayUserId(order.getMercUserId());
        if (Constant.PAY_TYPE_WECHAT.equals(order.getPayTypeCode()) || "sxfPay1".equals(order.getPayTypeCode())) {
            record.setPaySource(1);
        } else if (Constant.PAY_TYPE_ALIPAY.equals(order.getPayTypeCode()) || "sxfPay0".equals(order.getPayTypeCode())) {
            record.setPaySource(2);
        } else if (Constant.PAY_TYPE_YSFPAY.equals(order.getPayTypeCode()) || "sxfPay2".equals(order.getPayTypeCode())) {
            record.setPaySource(3);
        } else {
            record.setPaySource(4);
        }
        merchantMoveRecordsMapper.updateById(record);
        JSONObject payData = result.getJSONObject("payData");
        payData.put("orderNumber", order.getOrderNumber());
        payData.put("payType", params.get("payWay"));
        log.info("===============>组装支付参数:{}<==================", payData);
        return ResultGenerator.genSuccessResult("处理成功", payData);
    }

    /*Map<String,Object> result = new HashMap<>(2);
        String orderNumber = null;
        Double consumeFee = Double.parseDouble(params.get("comsumeMoney"));//消费金额
        String merchantCode = params.get("merchantCode");
        String storeId = params.get("storeId");
        //选择了会员卡支付
        if ("1".equals(params.get("isMember")) && "memberPay".equals(params.get("radioPay"))) {
            return toVipPay(params);
        }
        log.info("==============>选择直接支付，请求参数:{}<=================",params);
        MerchantStore store = merchantStoreService.getMerchantInfo(merchantCode,storeId);
        if(store == null){
            result.put("code", "0");
            result.put("msg", "店铺信息状态异常或不存在！");
            return result;
        }
        Map<String,Object> reqResult = null;
        String payTypeCode = "";
        String payTypeName = "";
        String payWay = params.get("payWay");
        if("1".equals(aisleSwitch)){
            orderNumber = "L" + StringUtil.getBillno();
            if ("ZFBZF".equals(payWay)) {
                payTypeCode = "leshuaPay0";
                payTypeName = "乐刷支付宝支付";
            } else if ("WXZF".equals(payWay)) {
                payTypeCode = "leshuaPay1";
                payTypeName = "乐刷微信支付";
            }
            //JSONObject jsonObject = converParameter(aisleSwitch,params,request,orderNumber);
            reqResult = leshuaService.tradePay(params,request,store,orderNumber);
        }else if("2".equals(aisleSwitch)){
            orderNumber = "SXF" + StringUtil.getBillno();
            if ("ZFBZF".equals(payWay)) {
                payTypeCode = "sxfPay0";
                payTypeName = "随行支付宝支付";
            } else if ("WXZF".equals(payWay)) {
                payTypeCode = "sxfPay1";
                payTypeName = "随行微信支付";
            }else{
                payTypeCode = "sxfPay2";
                payTypeName = "随行云闪付支付";
            }
            QueryWrapper<MerchantChannel> channelWrapper = new QueryWrapper<MerchantChannel>();
            channelWrapper.eq("channelCode","SXF");
            MerchantChannel channel = merchantChannelMapper.selectOne(channelWrapper);
            if(channel == null){
                result.put("code","0");
                result.put("msg","未配置随行付通道！");
                return result;
            }
            QueryWrapper<MerchantChannelStatus> channelStatusWrapper = new QueryWrapper<MerchantChannelStatus>();
            channelStatusWrapper.eq("channel",channel.getId());
            channelStatusWrapper.eq("merchantCode",merchantCode);
            MerchantChannelStatus channelStatus = merchantChannelStatusMapper.selectOne(channelStatusWrapper);
            if(channelStatus == null){
                result.put("code","0");
                result.put("msg","当前商户未查询到通道信息！");
                return result;
            }
            if(!channelStatus.isPayment()){
                result.put("code","0");
                result.put("msg","当前商户还未进件成功！");
                return result;
            }
            //reqResult = sxfPayService.tradePay(params, request,store,orderNumber,channelStatus);
        }else{
            result.put("code","0");
            result.put("msg","暂不支持其他支付通道！");
            return result;
        }
        if("0".equals(reqResult.get("code"))){
            return reqResult;
        }
        reqResult = (Map<String, Object>) reqResult.get("data");
        MerchantOrder merchantOrder = new MerchantOrder();
        merchantOrder.setMerchantCode(merchantCode);
        merchantOrder.setStoreId(store.getStoreId());
        merchantOrder.setStoreName(store.getStoreName());
        merchantOrder.setMerchantName(store.getMerchantName());
        merchantOrder.setOrderNumber(orderNumber);
        merchantOrder.setStaffCode(store.getStoreId());
        merchantOrder.setStaffName(store.getStoreName());
        merchantOrder.setPayTypeCode(payTypeCode);
        merchantOrder.setPayTypeName(payTypeName);
        merchantOrder.setConsumeFee(consumeFee);
        MerchantBaseInfo merchantBaseInfo = new MerchantBaseInfo();
        merchantBaseInfo.setMerchantCode(merchantCode);
        merchantBaseInfo = merchantBaseInfoService.queryMerchantBaseInfo(merchantBaseInfo);
        Double rate = merchantBaseInfo.getLeshuaRate() == null ? 0.0038d : merchantBaseInfo.getLeshuaRate();
        List<MerchantRate> myRateList = merchantRateMapper.selectList(new QueryWrapper<MerchantRate>().eq("userId", merchantBaseInfo.getUserId()));
        if(!myRateList.isEmpty()){
            rate = new BigDecimal(myRateList.get(0).getCurrentRate()).divide(new BigDecimal(10000)).doubleValue();
        }
        *//*QueryWrapper<UserApp> query = new QueryWrapper<UserApp>().eq("userId",merchantBaseInfo.getUserId());
        UserApp userApp = userAppService.getOne(query);
        if(userApp != null){
            rate = merchantOrderService.getCurrentFee(userApp,"current",rate,userApp.getUserId());
        }*//*
        BigDecimal fee = new BigDecimal(String.valueOf(consumeFee)).multiply(new BigDecimal(String.valueOf(rate))).setScale(2, BigDecimal.ROUND_HALF_UP);
        merchantOrder.setEnterFee(new BigDecimal(String.valueOf(consumeFee)).subtract(fee).doubleValue());
        Date date = new Date();
        merchantOrder.setCreateDt(date);
        merchantOrder.setUpdateTime(date);
        merchantOrder.setStatus("5");
        merchantOrder.setRemark(params.get("remark"));
        merchantOrder.setAisleSwitch(aisleSwitch);
        merchantOrder.setOrderType("2");
        merchantOrder.setUserImg(params.get("userImg"));
        merchantOrder.setNickName(URLEncoder.encode(params.get("nickName"), "UTF-8"));
        log.info("============zu zhuang dingdan xinxi======================" + JSONObject.toJSONString(merchantOrder));
        merchantOrder.setRate(new BigDecimal(String.valueOf(rate)).multiply(new BigDecimal(10000)).intValue());

        //-------------------
        if("WXZF".equalsIgnoreCase(params.get("payWay"))){
            merchantOrder.setMercUserId(params.get("openid"));
        }else if("ZFBZF".equalsIgnoreCase(params.get("payWay"))){
            merchantOrder.setMercUserId(params.get("userId"));
        }else if("UNIONPAY".equalsIgnoreCase(params.get("payWay"))){
            merchantOrder.setMercUserId(params.get("userId"));
        }

        //-------------------
        merchantOrderService.saveMerchantOrder(merchantOrder);
        result.put("aisleSwitch",aisleSwitch);
        result.put("code","1");
        result.put("msg","下单成功");
        result.put("data",reqResult);*/


    /**
     * 组装订单参数
     *
     * @param params
     * @return
     */
    private MerchantOrder getMerchantOrder(Map<String, Object> params) {

        String merchantCode = (String) params.get("merchantCode");
        String comsumeMoney = (String) params.get("comsumeMoney");
        MerchantStore store = (MerchantStore) params.get("store");
        MerchantChannelStatus channel = (MerchantChannelStatus) params.get("channel");

        MerchantBaseInfo merchant = (MerchantBaseInfo) params.get("merchant");

        MerchantOrder order = new MerchantOrder();
        order.setMerchantCode(merchantCode);
        order.setStoreId(store.getStoreId());
        order.setStoreName(store.getStoreName());
        order.setMerchantName(merchant.getAlias());
        order.setAlias(merchant.getMerchantName());
        order.setStaffCode(store.getStoreId());
        order.setStaffName(store.getStoreName());
        order.setConsumeFee(Double.valueOf(comsumeMoney));
        if (StringUtils.isNotEmpty((String) params.get("userId"))) {
            order.setMercUserId((String) params.get("userId"));
        } else {
            order.setMercUserId((String) params.get("openid"));
        }
        if(StringUtil.isNotEmpty(order.getMercUserId())){
            order.setMercUserId(order.getMercUserId().replace(" ", "+"));
        }
        if(params.get("mercOrderNo") != null){
            order.setMercOrderNo(params.get("mercOrderNo").toString());
        }
        if(params.get("mercNotifyUrl") != null){
            order.setMercNotifyUrl(params.get("mercNotifyUrl").toString());
        }
        if(params.get("mercRefundUrl") != null){
            order.setMercReturnUrl(params.get("mercRefundUrl").toString());
        }
        if(params.get("subject") != null){
            order.setSubject(params.get("subject").toString());
        }
        Date date = new Date();
        order.setCreateDt(date);
        order.setUpdateTime(date);
        order.setStatus("5");
        order.setRemark((String) params.get("remark"));
        String orderType = "2";
        if (StringUtils.isNotEmpty((String) params.get("payType")) && "03".equals(params.get("payType"))) {
            orderType = "3";
            order.setIsRecharge("1");
        }
        order.setOrderType(orderType);
        order.setMemberCode(params.get("memberCode") != null ? params.get("memberCode").toString() : "");
        order.setUserImg(params.get("userImg") != null ? (String) params.get("userImg") : "");
        if (params.get("nickName") != null) {
            try {
                order.setNickName(URLDecoder.decode((String) params.get("nickName"), "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                log.info("==================>解析会员名称失败");
            }
        }
        log.info("============组装订单信息======================" + JSONObject.toJSONString(order));
        //会员充值查询收银点信息
        String snNo = (String) params.get("snNo");
        //设置当前支持是否支持信用卡
        merchantCashPlaceService.setOrderPlaceInfo(order,snNo);
//        order.setDSource(params.get("dSource") == null ? "": params.get("dSource").toString());
        merchantOrderService.constOrderPayCodeAndName(order, params, channel);
        order.isAllowBankLarge(merchant);
        BigDecimal rate = merchantRateNewService.getMchRate(merchant.getMerchantCode(), order.getPayTypeCode(), order.getConsumeFee());
        order.calcRateAndFee(rate);
        if (StringUtils.isNotEmpty((String) params.get("ip"))) {
            String ip = params.get("ip").toString();
            order.setIp(ip);
            String ipAddress = IpUtils.getIpLoactionAddress(ipLocationService.getLocation(ip));
            order.setIpAddress(ipAddress);
        }
        return order;
    }

    /**
     * @param params
     */
    private void checkPayParams(Map<String, Object> params) {
        Object tk = params.get("tk");
        if(StringUtil.isNotEmpty(tk)){
            MercOrderToken byToken = mercOrderTokenService.getByToken(tk.toString());
            MsgException.checkNull(byToken, "tk参数有误");
            params.put("comsumeMoney",byToken.getOrderAmt().toString());
            params.put("merchantCode",byToken.getMerchantCode());
            Date now = DateUtils.currentDate();
            if(now.compareTo(byToken.getExpireTime()) > 0){
                MsgException.throwException("订单超时，请重新生成订单");
            }
            params.put("orderNumber",byToken.getOrderNumber());
            params.put("snNo",byToken.getSnNo());
            params.put("mercOrderNo",byToken.getMercOrderNo());
            params.put("mercNotifyUrl",byToken.getMercNotifyUrl());
            params.put("mercRefundUrl",byToken.getMercRefundUrl());
            params.put("subject",byToken.getSubject());
        }
        //检查交易参数
        MsgException.checkNull(params.get("comsumeMoney"), "无消费金额");
        MsgException.checkNull(params.get("merchantCode"), "无商户编号");
        MerchantStore store = null;

        if (params.get("storeId") != null) {
            store = merchantStoreService.getMerchantInfo((String) params.get("merchantCode"), (String) params.get("storeId"));
        } else {
            store = merchantStoreService.queryMerchantStore(new MerchantStore().setMerchantCode((String) params.get("merchantCode")));
        }
        MsgException.checkNull(store, "店铺信息状态异常或不存在！");
        MerchantChannelStatus channel = null;
        Object channelVal = params.get("channelVal");
        if (channelVal != null) {
            channel = merchantChannelStatusService.getByMerchantCode((String) params.get("merchantCode"), Integer.valueOf(channelVal.toString()));
        } else {
            channel = merchantChannelStatusService.getValidData((String) params.get("merchantCode"));
        }
        MsgException.checkNull(channel, "无进件信息，请先提交商户信息进行审核");

        MsgException.check("7".equals(channel.getStatus()), "实时到账审核中");

        MsgException.check("2".equals(store.getStatus()), "商户已被禁用");

        MsgException.check(!channel.isPayment(), "进件未通过请耐心等待或联系客服");

        QueryWrapper<MerchantBaseInfo> info = new QueryWrapper<MerchantBaseInfo>().
                eq("merchantCode", store.getMerchantCode());
        MerchantBaseInfo baseInfo = merchantBaseInfoService.getOne(info);
        MsgException.checkNull(baseInfo, "商户信息异常！");

        String accountName = (String) params.get("accountName");
        String accountPhone = (String) params.get("accountPhone");
        if (StringUtils.isNotEmpty(accountName) && StringUtils.isNotEmpty(accountPhone)) {
            AccountDTO realAccount = accountService.getRealAccount(baseInfo.getUserId());
            String checkName = realAccount.getBankCard().getBankHolder();
            String checkPhone = realAccount.getBankCard().getPhone();
            if (!accountName.equals(checkName) || !accountPhone.equals(checkPhone)) {
                MsgException.throwException("收款人姓名或手机号不正确，请与商户核实!");
            }
        }
        params.put("store", store);
        params.put("channel", channel);
        params.put("merchant", baseInfo);
    }


    private Map<String, Object> toVipPay(Map<String, Object> params) {
        Map<String, Object> result = new HashMap<>();
        log.info("==============>选择会员卡支付，请求参数:{}<=================", params);
        Double consumeFee = Double.parseDouble(params.get("comsumeMoney").toString());//消费金额
        String merchantCode = (String) params.get("merchantCode");
        String storeId = (String) params.get("storeId");

        MerchantMenber m = new MerchantMenber();
        m.setMerchantCode((String) params.get("merchantCode"));
        m.setStoreId((String) params.get("storeId"));
        if (StringUtils.isNotEmpty((String) params.get("appOpenId"))) {
            m.setAppOpenId((String) params.get("appOpenId"));
        } else {
            m.setOpenid((String) params.get("openid"));
        }
        //
        List<MerchantMenber> queryMerchantMenberList = merchantMenberService.queryMerchantMenberList(m);
        if (queryMerchantMenberList != null && queryMerchantMenberList.size() > 0) {
            ActivityConsumReturn activityConsumReturn = new ActivityConsumReturn();
            activityConsumReturn.setMerchantCode((String) params.get("merchantCode"));
            activityConsumReturn.setStoreId((String) params.get("storeId"));
            List<ActivityConsumReturn> queryActivityConsumReturnList = activityConsumReturnService.queryActivityConsumReturnList(activityConsumReturn);
            Double returnMoney = 0d;
            MerchantMenberComsume merchantMenberComsume = new MerchantMenberComsume();
            if (queryActivityConsumReturnList != null && queryActivityConsumReturnList.size() > 0) {
                queryActivityConsumReturnList = comsumeMoneyByDesc(queryActivityConsumReturnList);
                for (ActivityConsumReturn a : queryActivityConsumReturnList) {
                    if (1 == a.getTimeType()) {
                        if (a.getStartDt() == null || a.getEndDt() == null) {
                            continue;
                        }
                        boolean bol = DateUtils.isBoolean(a.getStartDt(), a.getEndDt());
                        if (!bol) {
                            activityConsumReturnService.deleteActivityConsumReturn(a);
                            continue;
                        }
                    }
                    if (null != a.getComsumeMoney()) {
                        //分等级返现
                        if (a.getType() == 0) {
                            if (consumeFee >= StringUtil.bigDecimal(a.getComsumeMoney())) {
                                merchantMenberComsume.setGiveMoney(StringUtil.bigDecimal(a.getReturnMoney()));// 返现金额
                                returnMoney = a.getReturnMoney();
                                break;
                            }
                        } else if (a.getType() == 1) {
                            if (consumeFee >= StringUtil.bigDecimal(a.getComsumeMoney())) {
                                Double d = a.getReturnMoney();
                                Double countD = consumeFee / a.getComsumeMoney();
                                Integer count = countD.intValue();
                                Double returnAmt = d * count;
                                merchantMenberComsume.setGiveMoney(StringUtil.bigDecimal(returnAmt));// 返现金额
                                returnMoney = StringUtil.bigDecimal(returnAmt);
                                break;
                            }
                        }
                    }
                    if (a.getType() == 2) {
                        Double percentRate = a.getPercent() / 100;
                        Double d = consumeFee * percentRate;
                        merchantMenberComsume.setGiveMoney(StringUtil.bigDecimal(d));// 返现金额
                        returnMoney = StringUtil.bigDecimal(d);
                        break;
                    }
                }
            }
            m = queryMerchantMenberList.get(0);
            Double usableRechargeFee = m.getUsableRechargeFee() == null ? 0d : m.getUsableRechargeFee();// 可用充值金额
            usableRechargeFee = StringUtil.bigDecimal(usableRechargeFee);
            Double usableGiveFee = m.getUsableGiveFee() == null ? 0d : m.getUsableGiveFee();// 可用的赠送金额
            usableGiveFee = StringUtil.bigDecimal(usableGiveFee);
            Double count = usableGiveFee + usableRechargeFee;
            if (consumeFee > count) {
                log.info("===============>会员卡充值，余额不足，会员卡消费金额:{},会员卡余额:{}<============", consumeFee, count);
                result.put("code", "0");
                result.put("msg", "会员卡余额不足");
                return result;
            } else {
                if (usableGiveFee >= consumeFee) {// 可用的赠送余额大于等于消费金额
                    usableGiveFee = usableGiveFee - consumeFee;// 扣款之后的赠送金额
                } else {// 可用的赠送余额小于消费金额
                    usableGiveFee = 0d;
                    usableRechargeFee = count - consumeFee;
                }
                MerchantMenber menber = new MerchantMenber();
                menber.setUsableGiveFee(usableGiveFee);
                menber.setUsableRechargeFee(usableRechargeFee);
                Double comsumeMoney = m.getComsumeMoney() == null ? 0d : m.getComsumeMoney();// 之前会员的消费金额
                menber.setComsumeMoney(StringUtil.bigDecimal(consumeFee + comsumeMoney));// 现在的会员消费金额
                Double totalGiveFee = m.getTotalGiveFee() == null ? 0d : m.getTotalGiveFee();
                totalGiveFee = totalGiveFee + returnMoney;// 赠送总余额
                menber.setTotalGiveFee(totalGiveFee);
                menber.setUsableGiveFee(usableGiveFee + returnMoney);// 赠送总可用余额
                menber.setId(m.getId());
                merchantMenberService.updateMerchantMenber(menber);// 修改会员表余额
                MerchantStore merchantStore = new MerchantStore();
                merchantStore.setStoreId((String) params.get("storeId"));
                merchantStore.setMerchantCode((String) params.get("merchantCode"));
                merchantStore = merchantStoreService.queryMerchantStore(merchantStore);
                String orderNo = "XF700" + StringUtil.getBillno();
                merchantMenberComsume = merchantMenberComsume.convert(orderNo, merchantMenberComsume.getGiveMoney(), m, merchantStore, consumeFee, merchantCode);
                merchantMenberComsumeService.saveMerchantMenberComsume(merchantMenberComsume);
                MemberOrder memberOrder = new MemberOrder();
                // 订单号
                try {
                    memberOrder.setMerchantCode(merchantCode);
                    memberOrder.setMerchantName(merchantStore.getMerchantName());
                    memberOrder.setStoreId(storeId);
                    memberOrder.setStoreName(merchantStore.getStoreName());
                    memberOrder.setOrderNumber(orderNo);
                    memberOrder.setMemberCode(m.getMemberCode());
                    Date date = new Date();
                    memberOrder.setCreateDt(date);
                    memberOrder.setOrderFee(consumeFee + "");// 订单金额
                    memberOrder.setNickName(m.getNickName());
                    memberOrder.setOrderType("0");
                    memberOrder.setOrderStatus("1");
                    memberOrder.setStaffCode(storeId);
                    memberOrder.setStaffName(merchantStore.getStoreName());
                    memberOrderService.saveMemberOrder(memberOrder);
                    result.put("isMember", "1");
                    MerchantBaseInfo merchantBaseInfo = new MerchantBaseInfo();
                    merchantBaseInfo.setMerchantCode(memberOrder.getMerchantCode());
                    List<MerchantBaseInfo> queryMerchantBaseInfoList = merchantBaseInfoService.queryMerchantBaseInfoList(merchantBaseInfo);
                    if (queryMerchantBaseInfoList != null && queryMerchantBaseInfoList.size() > 0) {
                        merchantBaseInfo = queryMerchantBaseInfoList.get(0);
                        if (StringUtils.isNotEmpty(merchantBaseInfo.getUserId())) {
                            UserVoice voice = userVoiceService.getByUserId(Long.valueOf(merchantBaseInfo.getUserId()));
                            if(UserVoice.ENABLE.equals(voice.getMemberConsume())){
                                List<String> alias = userAppService.storeMemberList(merchantCode);
                                generalPushUtil.sendAllPlatByUserIdConsumeWithCoupon(alias,BigDecimal.valueOf(consumeFee),BigDecimal.valueOf(returnMoney));
                            }
                        }
                    }
                    result.put("code", "1");
                    result.put("msg", "会员卡支付成功！");
                    //TODO 调用语音播报
                    try {
                        MerchantOrder order = new MerchantOrder();
                        order.setConsumeFee(consumeFee);
                        order.setMerchantCode((String) params.get("merchantCode"));
                        order.setOrderNumber(orderNo);
                        order.setDiscount(returnMoney);
                        notifyMessageService.sendMqttMessage(order, date, "pay", null, null, PayMessageType.MEMBER_CONSUME.getValue());

                        menber.setCardNo(m.getCardNo());
                        menber.setMerchantCode(m.getMerchantCode());
                        menber.setOpenid(m.getOpenid());
                        merchantMenberService.sendMenberBalanceChangeNotice(menber,consumeFee,"2");
                    } catch (Exception e) {
                        log.info("===========>会员卡支付，其他操作失败，失败原因:{}，<==============", e.getMessage());
                    }
                    return result;
                } catch (NumberFormatException e) {
                    e.printStackTrace();
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    result.put("code", "0");
                    result.put("msg", "会员卡支付失败！");
                    result.put("isMember", "0");
                    return result;
                }
            }
        } else {
            result.put("code", "0");
            result.put("msg", "会员卡支付失败！");
            result.put("isMember", "0");
            return result;
        }
    }

    public List<ActivityConsumReturn> comsumeMoneyByDesc(List<ActivityConsumReturn> list) {
        list.sort((o1, o2) -> (int) (Optional.ofNullable(o2.getComsumeMoney()).orElse(0d) - Optional.ofNullable(o1.getComsumeMoney()).orElse(0d)));
        return list;
    }

    /**
     * 会员升级付费
     *
     * @param levelDTO
     * @return
     */
    @Deprecated
    @Override
    public Map<String, Object> tradePay(LevelDTO levelDTO, HttpServletRequest request) throws Exception {
        MsgException.throwException("改方法已过时");
//        Map<String,Object> result = new HashMap<>(2);
//        String aisleSwitch = systemConfigService.querySystemConfigValue("aisleSwitch");
//        if(StringUtil.isEmpty(aisleSwitch)){
//            result.put("code","0");
//            result.put("msg","未配置支付通道！");
//            return result;
//        }
//        String orderNumber = "SJ000"+StringUtil.getBillno();
//        Map<String,String> params = new HashMap<>();
//        params.put("payWay",levelDTO.getPayWay());
//        params.put("comsumeMoney",levelDTO.getMoney());
//        params.put("openid",levelDTO.getOpenid());
//        params.put("userId",levelDTO.getUserid());
//
//        String merchantCode = "M800202008254990744";
//
//        //创建用户升级订单//
//        MerchantIncome income=new MerchantIncome();
//        income.setUserId(Integer.parseInt(levelDTO.getUserAppId()));
//        income.setDealCode(orderNumber);
//        income.setCreateTime(new Date());
//        income.setDealFee(Double.valueOf(levelDTO.getMoney()));
//        income.setPayTypeCode("3");
//        income.setPayTypeName("推广员升级充值");
//        income.setMerchantCode(merchantCode);
//        QueryWrapper<MerchantBaseInfo> queryWrapper = new QueryWrapper<MerchantBaseInfo>().eq("merchantCode",merchantCode);
//        MerchantBaseInfo one = merchantBaseInfoService.getOne(queryWrapper);
//        if(one == null){
//            log.error("======================>升级金额打款的商户编号数据不存在，商编为：{}<=====================",merchantCode);
//            result.put("code","0");
//            result.put("msg","支付失败！");
//            return result;
//        }
//        income.setMerchantName(one.getAlias());
//        income.setDealStatus(0);
//        merchantIncomeMapper.saveMerchantIncome(income);
//        MerchantStore store = new MerchantStore();
//        store.setMerchantName(one.getMerchantName());
//        store.setAlias(one.getAlias());
//
//        QueryWrapper<MerchantChannel> channelWrapper = new QueryWrapper<MerchantChannel>();
//        channelWrapper.eq("channelCode","SXF");
//        MerchantChannel channel = merchantChannelMapper.selectOne(channelWrapper);
//        if(channel == null){
//            result.put("code","0");
//            result.put("msg","未配置随行付通道！");
//            return result;
//        }
//        MerchantChannelStatus channelStatus = merchantChannelStatusService.getByMerchantCode(merchantCode,channel.getId());
//        if(channelStatus == null){
//            result.put("code","0");
//            result.put("msg","当前商户未查询到通道信息！");
//            return result;
//        }
//        if(!channelStatus.isPayment()){
//            result.put("code","0");
//            result.put("msg","当前商户还未进件成功！");
//            return result;
//        }
//
//        String payTypeCode = null;
//        String payTypeName = null;
//        if ("ZFBZF".equals(levelDTO.getPayWay())) {
//            payTypeCode = "sxfPay0";
//            payTypeName = "随行支付宝支付";
//        } else if ("WXZF".equals(levelDTO.getPayWay())) {
//            payTypeCode = "sxfPay1";
//            payTypeName = "随行微信支付";
//        }else{
//            payTypeCode = "sxfPay2";
//            payTypeName = "随行云闪付支付";
//        }
//        MerchantOrder merchantOrder = new MerchantOrder();
//        merchantOrder.setMerchantCode(merchantCode);
//        merchantOrder.setStoreId(store.getStoreId());
//        merchantOrder.setStoreName(store.getStoreName());
//        merchantOrder.setMerchantName(store.getMerchantName());
//        merchantOrder.setOrderNumber(orderNumber);
//        merchantOrder.setStaffCode(store.getStoreId());
//        merchantOrder.setStaffName(store.getStoreName());
//        merchantOrder.setPayTypeCode(payTypeCode);
//        merchantOrder.setPayTypeName(payTypeName);
//        merchantOrder.setConsumeFee(Double.valueOf(levelDTO.getMoney()));
//        Date date = new Date();
//        merchantOrder.setCreateDt(date);
//        merchantOrder.setUpdateTime(date);
//        merchantOrder.setStatus("5");
//        merchantOrder.setRemark(params.get("remark"));
//        merchantOrder.setAisleSwitch(aisleSwitch);
//        merchantOrder.setOrderType("8");
//
//        BigDecimal rate = merchantRateNewService.getMchRate(one.getMerchantCode(),payTypeCode, merchantOrder.getConsumeFee());
//        merchantOrder.calcRateAndFee(rate);
//
//        merchantOrderService.save(merchantOrder);
        //return sxfPayService.tradePay(params, request, store, orderNumber, channelStatus);
        return null;
    }

    /**
     * 被扫小程序会员卡充值接口
     *
     * @param json
     * @return
     */
    @Override
    public Result<JSONObject> memberRecharge(JSONObject json) {

        // 校验会员充值参数
        checkRechargeParams(json);
        //组装订单参数
        MerchantChannelStatus channel = json.getObject("channel", MerchantChannelStatus.class);
        MerchantStore store = json.getObject("store", MerchantStore.class);
        MerchantMenber menber = json.getObject("menber", MerchantMenber.class);

        MerchantBaseInfo merchant = json.getObject("merchant", MerchantBaseInfo.class);

        Map<String, Object> params = new HashMap<>(16);
        params.put("payWay", json.getString("payWay"));
        params.put("merchantCode", channel.getMerchantCode());
        params.put("comsumeMoney", json.get("rechargeAmt"));

        params.put("channel", channel);
        params.put("merchant", merchant);
        params.put("store", store);
        params.put("userImg", menber.getLogo());
        params.put("nickName", menber.getNickName() == null ? menber.getMemberName() : menber.getNickName());
        params.put("orderNum", "HYCZ");
        params.put("userId", json.getString("appOpenId"));
        params.put("payType", json.getString("payType"));

        params.put("ip", json.getString("ip"));
        params.put("memberCode", menber.getMemberCode());
        MerchantOrder order = getMerchantOrder(params);
        /**
         * 组装会员充值订单
         */
        MemberOrder menberOrder = getMenberOrder(order);

        JSONObject result = null;
        //随行付
        if (channel.getChannel() == 1) {
            result = sxfPayService.tradePay(order, channel,merchant);
            //乐刷
        } else if (channel.getChannel() == 2) {
            MsgException.throwException("当前通道已关闭");
        } else if (channel.getChannel() == 3) {
            //瑞银信
            result = ryxPayService.tradePay(order, channel,merchant);
        } else if (channel.getChannel() == 4) {
            //银盛
            result = ysPayOldService.tradePay(order, channel,merchant);
        } else {
            MsgException.throwException("未知通道");
        }
        if (ResultCode.SUCCESS.code() != result.getInteger("code")) {
            return ResultGenerator.genFailResult(result.getString("msg"));
        }
        merchantOrderService.save(order);
        memberOrderService.saveMemberOrder(menberOrder);
        JSONObject payData = result.getJSONObject("payData");
        return ResultGenerator.genSuccessResult("处理成功", payData);
    }

    /**
     * 组装会员充值订单
     */
    private MemberOrder getMenberOrder(MerchantOrder merchantOrder) {
        MemberOrder memberOrder = new MemberOrder();
        memberOrder.setOrderFee(String.valueOf(merchantOrder.getConsumeFee()));
        memberOrder.setMemberCode(merchantOrder.getMemberCode());
        memberOrder.setMerchantCode(merchantOrder.getMerchantCode());
        memberOrder.setMerchantName(merchantOrder.getMerchantName());
        memberOrder.setStoreId(merchantOrder.getStoreId());
        memberOrder.setStoreName(merchantOrder.getStoreName());
        memberOrder.setCreateDt(new Date());
        memberOrder.setNickName(merchantOrder.getNickName());
        memberOrder.setLogo(merchantOrder.getUserImg());
        memberOrder.setOrderStatus("2");
        memberOrder.setOrderType("1");
        memberOrder.setRechargeType("3");
        memberOrder.setOrderNumber(merchantOrder.getOrderNumber());
        memberOrder.setMemberCode(merchantOrder.getMemberCode());
        log.info("=======wechatPay:fangfa" + JSONObject.toJSONString(memberOrder) + "");
//        memberOrderService.saveMemberOrder(memberOrder);
        return memberOrder;
    }

    /**
     * 校验小程序会员充值参数
     *
     * @param json
     */
    private void checkRechargeParams(JSONObject json) {
        MsgException.checkNull(json.getInteger("storeId"), "店铺ID为空！");
        MsgException.checkBlank(json.getString("appOpenId"), "充值用户为空！");
        MsgException.checkNull(json.getBigDecimal("rechargeAmt"), "充值金额为空！");
        MsgException.check(!StringUtil.isNumber(json.getBigDecimal("rechargeAmt").toString()), "充值金额格式不正确！");
        MsgException.check(json.getBigDecimal("rechargeAmt").doubleValue() < 0.01d, "充值金额最少为0.01！");

        MsgException.checkBlank(json.getString("payWay"), "支付渠道为空！");
        MsgException.checkBlank(json.getString("payType"), "支付方式为空！");

        MerchantStore mStore = new MerchantStore();
        mStore.setId(json.getInteger("storeId"));
        MerchantStore store = merchantStoreService.queryMerchantStore(mStore);
        MsgException.checkNull(store, "店铺数据异常！");
        MsgException.check("2".equals(store.getStatus()), "店铺已被禁用！");

        QueryWrapper<MerchantBaseInfo> info = new QueryWrapper<MerchantBaseInfo>().
                eq("merchantCode", store.getMerchantCode());
        MerchantBaseInfo baseInfo = merchantBaseInfoService.getOne(info);
        MsgException.checkNull(baseInfo, "商户信息异常！");

        QueryWrapper<MerchantMenber> queryWrapper = new QueryWrapper<MerchantMenber>().eq("storeId", store.getStoreId())
                .eq("appOpenId", json.getString("appOpenId"));
        MerchantMenber menber = merchantMenberService.getOne(queryWrapper);
        MsgException.checkNull(menber, "会员数据异常！");

        MerchantChannelStatus channel = merchantChannelStatusService.getValidData(baseInfo.getMerchantCode());
        MsgException.checkNull(channel, "未获取到商户进件信息，请先提交商户信息");
        MsgException.check("7".equals(channel.getStatus()), "实时到账审核中，请耐心等待或者联系客服！");
        MsgException.check(!channel.isPayment(), "当前进件状态未通过，请耐心等待或联系客服！");

        // 全局电子围栏和单商户电子围栏判定
        if (!commonSwitchService.allowEcdemicPay() && !store.allowEcdemicPay()) {
            // 不允许异地支付的时候需要校验ip和商户所在城市
            try {
                String ip = json.getString("ip");
                String province = json.getString("province");
                checkPayLocation(ip, baseInfo,province);
            } catch (PayRiskException e) {
                MsgException.throwException(e.getMessage());
            }
        }
        json.put("store", store);
        json.put("merchant", baseInfo);
        json.put("channel", channel);
        json.put("menber", menber);
        json.put("alias", baseInfo.getAlias());
    }


    @Override
    public ModelAndView scanPayAuth(HttpServletRequest request, HttpServletResponse response, String tk) {
        ModelAndView modelAndView = new ModelAndView("merchant/errorInfo2");
        if (StringUtil.isEmpty(tk)) {
            modelAndView.addObject("error", "缺失参数！");
            return modelAndView;
        }
        String APP_ID = ParametersUtil.APPID;
        String ali_appid = ParametersUtil.ZY_ALI_APP_ID;
        String domain_wap = ParametersUtil.domain + "/wap";
        String url = "/merchant/scanPay?tk=" + tk;
        String ua = request.getHeader("user-agent").toLowerCase();
        String payType = "";
        String jump = "";
        try {
            if(ua.contains("micromessenger")){
                payType = "WXZF";
                jump = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + APP_ID
                        + "&redirect_uri=" + java.net.URLEncoder.encode(domain_wap + url, "utf-8")
                        + "&response_type=code&scope=snsapi_base&state=123#wechat_redirect";
            }else if(ua.contains("alipay")){
                payType = "ZFBZF";
                String toUrl = domain_wap + url;
                String rurl = java.net.URLEncoder.encode(toUrl, "utf-8");
                jump = "https://openauth.alipay.com/oauth2/publicAppAuthorize.htm?app_id=" + ali_appid + "&scope=auth_base&redirect_uri=" + rurl;
            }else{
                payType = "UNIONPAY";
                String toUrl = domain_wap + url;
                String rurl = java.net.URLEncoder.encode(toUrl, "utf-8");
                jump = "https://qr.95516.com/qrcGtwWeb-web/api/userAuth?version=1.0.0&redirectUrl=" + rurl;
            }
            String cokusName = "cokus_"+payType;
            Cookie[] cookies = request.getCookies();
            String cokus = "";
            if(cookies != null && cookies.length > 0){
                for (Cookie c:cookies) {
                    if(cokusName.equals(c.getName())){
                        String cValue = c.getValue();
                        if(StringUtil.isNotEmpty(cValue)){
                            //TODO 解决银联用户标识转码后特殊字符异常
                            if("UNIONPAY".equals(payType)){
                                cValue = cValue.replace(" ", "+");
                            }
                            byte[] decode = Base64.getDecoder().decode(cValue.getBytes(StandardCharsets.UTF_8));
                            cokus = new String(decode,0,0,decode.length);
                            break;
                        }
                    }
                }
            }
            if(StringUtil.isNotEmpty(cokus)){
                url = url+ "&userId="+cokus+"&payType="+payType;
                response.sendRedirect(domain_wap + url);
                return null;
            }else{
                response.sendRedirect(jump);
                return null;
            }
        }catch (Exception e){
            return null;
        }
    }
    /**
     * 扫码订单支付
     * @date: 2021/12/28 14:10
     * @param request:
     * @param tk:
     * @param code:
     * @param auth_code:
     * @param userAuthCode:
     * @return org.springframework.web.servlet.ModelAndView
     */
    @Override
    public ModelAndView scanPay(HttpServletRequest request,HttpServletResponse response,String tk, String code, String auth_code, String userAuthCode,String cokus,String payType) {
        ModelAndView view = new ModelAndView("merchant/errorInfo2");
        if(StringUtil.isEmpty(tk)){
            view.addObject("error", "缺失参数！");
            return view;
        }
        try {
            MercOrderToken orderToken = mercOrderTokenService.getByToken(tk);
            String orderAmt = orderToken.getOrderAmt().toString();
            String merchantCode = orderToken.getMerchantCode();
            String merchantName = orderToken.getMerchantName();
            view.addObject("tk",orderToken.getToken());
            if(StringUtil.isNotEmpty(cokus)){
                view.addObject("userId",cokus);
                view.addObject("payWay",payType);
            }else{
                if(StringUtil.isEmpty(code) && StringUtil.isEmpty(auth_code) && StringUtil.isEmpty(userAuthCode)){
                    view.addObject("error", "请使用支付宝微信或云闪付扫码！");
                    return view;
                }
                if(StringUtil.isNotEmpty(code)){
                    view.addObject("payWay","WXZF");
                    WxAccessTokenRequest tokenRequest = WxAccessTokenRequest.buidWxToken(ParametersUtil.APPID,ParametersUtil.APPSECRET,code, WxConstants.OAUTH2_ACCESS_TOKEN_URL);
                    WxOauth2AccessTokenResponse params = wxCommonService.getOauth2Info(tokenRequest);
                    view.addObject("userId", params.getOpenid());
                    view.addObject("unionId", params.getUnionid());
                }else if(StringUtil.isNotEmpty(auth_code)){
                    //支付宝取消主动授权 采用静默授权方式，无法获取用户信息
                    view.addObject("payWay","ZFBZF");
                    AlipaySystemOauthTokenResponse tokenResponse = AliUtil.getAliUserIdV2(auth_code, ParametersUtil.ZY_PRI, ParametersUtil.ZY_PUB, ParametersUtil.ZY_ALI_APP_ID);
                    view.addObject("userId", tokenResponse.getUserId());
                }else{
                    view.addObject("payWay","UNIONPAY");
                    try {
                        String ua = request.getHeader("User-Agent");
                        int begin = ua.indexOf("UnionPay");
                        String payMentApp = ua.substring(begin);
                        if(payMentApp.length() > 30){
                            payMentApp = payMentApp.substring(0,30);
                        }
                        MerchantChannelStatus channel = merchantChannelStatusService.getValidData(merchantCode);
                        Map<String, Object> unionInfo = new HashMap<>(3);
                        if(channel.getChannel() == 1){
                            unionInfo = sxfPayService.getUnionInfo(userAuthCode, payMentApp,null);
                        }else if(channel.getChannel() == 2){
                            view.addObject("error", "当前通道已关闭！");
                            return view;
                        }else if(channel.getChannel() == 3){
                            unionInfo = ryxPayService.getUnionInfo(userAuthCode,payMentApp,channel.getMerchantId());
                        }else if(channel.getChannel() == 4){
                            unionInfo = ysPayOldService.getUnionInfo(userAuthCode, payMentApp,null);
                        }else {
                            view.addObject("error", "未知通道类型");
                            return view;
                        }
                        log.info("===================>【银联】获取用户标识结果参数:{}==============", unionInfo);
                        if ("1".equals(unionInfo.get("code"))) {
                            Object userIdData = unionInfo.get("data");
                            String userId = "";
                            if(userIdData instanceof Map){
                                Map<String, String> data = (Map<String, String>) userIdData;
                                userId = data.get("data");
                            }else{
                                userId = userIdData.toString();
                            }
                            view.addObject("userId", userId);
                        }
                    }catch (Exception e){
                        e.printStackTrace();
                        view.addObject("error", "获取银联标识报错");
                        return view;
                    }
                }
                if(StringUtil.isNotEmpty(view.getModel().get("userId"))){
                    String cokusName = "cokus_"+view.getModel().get("payWay").toString();
                    String cokusId = Base64.getEncoder().encodeToString(view.getModel().get("userId").toString().getBytes(StandardCharsets.UTF_8));
                    Cookie cookie = new Cookie(cokusName,cokusId);
                    cookie.setMaxAge(-1);
                    response.addCookie(cookie);
                }
            }
            Date endTime = orderToken.getExpireTime();
            Date now = new Date();
            if(endTime.compareTo(now) < 0){
                view.addObject("error", "当前订单已过期！");
                return view;
            }else{
                long times = endTime.getTime() - now.getTime();
                long day = times / (24 * 60 * 60 * 1000);
                long hour = (times / (60 * 60 * 1000) - day * 24);
                long min = ((times / (60 * 1000)) - day * 24 * 60 - hour * 60);
                long sec = (times / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
                view.addObject("min",min == 0L ? "00" : min < 10 ? "0" + min: min);
                view.addObject("sec",sec == 0L ? "00" : sec < 10 ? "0" + sec: sec);
            }
//            view.addObject("merchantCode",merchantCode);
            view.addObject("storeName",merchantName);
            view.addObject("payAmt",orderAmt);
            view.setViewName("th_device_pay");
            return view;
        }catch (Exception e){
            e.printStackTrace();
            view.addObject("error", "参数解析异常！");
            return view;
        }
    }
}
