package cn.pluss.platform.channel.ys.impl;

import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.Sign;
import cn.hutool.crypto.asymmetric.SignAlgorithm;
import cn.pluss.platform.IdCardService;
import cn.pluss.platform.channel.MercAuditListener;
import cn.pluss.platform.converter.Converter;
import cn.pluss.platform.dto.AccountDTO;
import cn.pluss.platform.dto.BankCardDTO;
import cn.pluss.platform.entity.*;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.klk.vo.CallBackVo;
import cn.pluss.platform.klk.vo.FeesSetVo;
import cn.pluss.platform.mapper.AccountMapper;
import cn.pluss.platform.mapper.MerchantChannelFeeMapper;
import cn.pluss.platform.mapper.UserAppMapper;
import cn.pluss.platform.mcc.MccReflectService;
import cn.pluss.platform.merchant.AccountService;
import cn.pluss.platform.merchant.JftMercPaymentChannelService;
import cn.pluss.platform.merchant.MerchantBaseInfoService;
import cn.pluss.platform.merchantChannelStatus.MerchantChannelStatusService;
import cn.pluss.platform.merchantImage.MerchantImageService;
import cn.pluss.platform.notice.NoticeService;
import cn.pluss.platform.pojo.CombineMercInfo;
import cn.pluss.platform.region.RegionReflectService;
import cn.pluss.platform.subMerchant.SubMerchantService;
import cn.pluss.platform.task.SxfMerAuditHandler;
import cn.pluss.platform.user.impl.GeneralPushUtil;
import cn.pluss.platform.util.OssOperatUtil;
import cn.pluss.platform.util.SignUtils;
import cn.pluss.platform.vo.MerchantRateNewVO;
import cn.pluss.platform.ys.YsConfig;
import cn.pluss.platform.ys.impl.v20210929.YsConstant;
import cn.pluss.platform.ys.impl.v20220527.ReqMethod;
import cn.pluss.platform.ys.impl.v20220527.RespEntity;
import cn.pluss.platform.ys.impl.v20220527.YsConfigV3;
import cn.pluss.platform.ys.impl.v20220527.YsServiceV3;
import cn.pluss.platform.ys.impl.v20220527.entity.*;
import cn.pluss.platform.ys.impl.v20220527.service.YsAuditServiceV3;
import cn.pluss.platform.ysExtension.v20220615.YsConstantV3;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
//import cn.pluss.platform.merchant.edit.MercChangeRecordService;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;

import java.io.*;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.ExecutorService;

import static cn.pluss.platform.entity.MerchantBaseInfo.MERCH_TYPE_MICRO;

/**
 * @author lyf
 */
@Slf4j
@Service("ysAuditServiceV3")
public class YSAuditServiceV3 implements cn.pluss.platform.channel.ys.YSAuditServiceV3 {
    @Autowired
    private MerchantBaseInfoService mbiService;
    @Resource
    private AccountMapper accountMapper;
    @Autowired
    protected MerchantChannelStatusService mcsService;
    @Autowired
    private JftMercPaymentChannelService mpcService;
    @Autowired
    private TransactionTemplate transactionTemplate;
    @Autowired
    private YsServiceV3 ysServiceV3;
    @Autowired
    private AccountService accountService;
    @Autowired
    private IdCardService idCardService;
    @Autowired
    private YsConfigV3 ysConfigV3;
    @Autowired
    private RegionReflectService regionReflectService;
    @Autowired
    private ExecutorService executorService;
    @Autowired
    private MerchantImageService miService;
    @Autowired
    private YSAuditServiceV3 self;
    @Autowired
    private MercAuditListener mercAuditListener;
    @Autowired
    private NoticeService noticeService;
    @Autowired
    private GeneralPushUtil generalPushUtil;
    @Autowired
    private YsConfig ysConfig;
    @Autowired
    private MccReflectService reflectService;
    @Resource
    private UserAppMapper userAppMapper;
    @Autowired
    private SxfMerAuditHandler sxfMerAuditHandler;
    @Autowired
    private SubMerchantService smService;
    @Resource
    private SxfMerAuditHandler handler;
    @Resource
    private MerchantChannelFeeMapper merchantChannelFeeMapper;
//    @Autowired
//    private MercChangeRecordService mcrService;

    @Override
    public void merchantAuditV3(String userId, boolean isFailCheck, Integer channel) {
        try {
            self.step1(userId,channel);
            executorService.execute(() -> {
                try {
                    self.step2(userId,channel);
                    Thread.sleep(10000);
                    self.step3(userId, channel);
                } catch (Exception e) {
                    e.printStackTrace();

                    MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByUserId(userId);
                    MerchantChannelStatus mcs = mcsService.getByMerchantCode(mbi.getMerchantCode(), channel);

                    if (e instanceof MsgException) {
                        Serializable obj = ((MsgException) e).getObj();
                        if (obj instanceof RespEntity) {
                            mcs.getExtra().putAll((JSONObject) JSON.toJSON(obj));
                        }
                    }

                    if (mcs != null && mcs.getChannel().equals(channel)) {
                        mcs.setStatus(MerchantChannelStatus.AUDIT_STATUS_EXAMINING);
                        mcs.setThirdStatus(MerchantChannelStatus.AUDIT_THIRD_STATUS_WAITING);
                        mcs.setRemark("银盛审核失败: " + e.getMessage());
                        mcs.setUpdateTime(new Date());
                        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
                            @Override
                            protected void doInTransactionWithoutResult(TransactionStatus status) {
                                mcsService.updateById(mcs);
                            }
                        });
                    }
                }
            });
        } catch (Exception e) {
            e.printStackTrace();

            MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByUserId(userId);
            MerchantChannelStatus mcs = mcsService.getByMerchantCode(mbi.getMerchantCode(), channel);

            if (mcs != null && Objects.equals(mcs.getChannel(), channel)) {
                mcs.setStatus(MerchantChannelStatus.AUDIT_STATUS_EXAMINING);
                mcs.setThirdStatus(MerchantChannelStatus.AUDIT_THIRD_STATUS_WAITING);
                mcs.setRemark("银盛审核失败: " + e.getMessage());
                mcs.setUpdateTime(new Date());

                // 这里将驳回的信息放入新的事务中，防止被回滚
                transactionTemplate.execute(new TransactionCallbackWithoutResult() {
                    @Override
                    protected void doInTransactionWithoutResult(TransactionStatus status) {
                        mcsService.updateById(mcs);
                    }
                });
            }

            throw e;
        }
    }

    @Override
    public void sign(MerchantChannelStatus mcs, Integer channel) {
        List<String> excludeStatus = Collections.singletonList(MerchantChannelStatus.AUDIT_STATUS_SUCCESS);

        boolean returnFlag = excludeStatus.stream().anyMatch(s -> s.equals(mcs.getStatus()));

        if (returnFlag) {
            return;
        }

        MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByMerchantCode(mcs.getMerchantCode());
        mcs.setStatus(MerchantChannelStatus.AUDIT_STATUS_WAITING_SIGN);
        mcsService.updateById(mcs);

        JSONObject extra = mcs.getExtra();
        String custId = extra.getString("custId");
        RespEntity respEntity;
        if(channel == 4) {
            RateInfo rateInfo = new RateInfo();
            rateInfo.setCustId(custId);
            rateInfo.setBusOpenType("00|01");
            rateInfo.setContractType("2");
            rateInfo.setIsSendConMsg("1");
            rateInfo.setNotifyUrl(YsConfigV3.AUDIT_SIGN_NOTIFY_URL);

            RateFeeInfo rateFeeInfo = new RateFeeInfo();
            rateFeeInfo.setAliPayFee(new RateFeeDetail("0", "0.38", "1"));
            rateFeeInfo.setWxPayFee(new RateFeeDetail("0", "0.38", "1"));
            rateFeeInfo.setBank1debitPayFee(new RateFeeDetail("0", "0.61", "1", "999900"));
            rateFeeInfo.setBank1creditPayFee(new RateFeeDetail("0", "0.61", "1", "999900"));
            rateFeeInfo.setBank2debitPayFee(new RateFeeDetail("0", "0.60", "1", "999900"));
            rateFeeInfo.setBank2creditPayFee(new RateFeeDetail("0", "0.60", "1"));
            RateFeeDetail codeScanD0Fee = new RateFeeDetail("0", "0.10", "1");
            rateInfo.setCodeScanD0Fee(codeScanD0Fee);
            rateInfo.setCodeScanT1Fee(rateFeeInfo);

            respEntity = ysServiceV3.req(ReqMethod.sign, (JSONObject) JSON.toJSON(rateInfo), channel);
            if (!Objects.equals(respEntity.getSubCode(), YsConfigV3.BIZ_SUCCESS)) {
                throw new MsgException("银盛云商服3.0商户签约申请请求失败, {}", respEntity.getSubMsg());
            }
            //保存费率
            channelFee(0.48d,0.48d, channel, mcs.getMerchantCode());
        }else {
            RateInfoD1 rateInfoD1 = new RateInfoD1();
            rateInfoD1.setCustId(custId);
            rateInfoD1.setBusOpenType("00");
            rateInfoD1.setContractType("2");
            rateInfoD1.setIsSendConMsg("1");
            rateInfoD1.setNotifyUrl(YsConfigV3.AUDIT_NOTIFY_URL_D1);

            RateFeeInfo rateFeeInfo = new RateFeeInfo();
            rateFeeInfo.setAliPayFee(new RateFeeDetail("0", "0.38", "1"));
            rateFeeInfo.setWxPayFee(new RateFeeDetail("0", "0.38", "1"));
            rateFeeInfo.setBank1debitPayFee(new RateFeeDetail("0", "0.61", "1", "999900"));
            rateFeeInfo.setBank1creditPayFee(new RateFeeDetail("0", "0.61", "1", "999900"));
            rateFeeInfo.setBank2debitPayFee(new RateFeeDetail("0", "0.60", "1", "999900"));
            rateFeeInfo.setBank2creditPayFee(new RateFeeDetail("0", "0.60", "1"));
            rateInfoD1.setCodeScanT1Fee(rateFeeInfo);

            respEntity = ysServiceV3.req(ReqMethod.sign, (JSONObject) JSON.toJSON(rateInfoD1), channel);
            if (!Objects.equals(respEntity.getSubCode(), YsConfigV3.BIZ_SUCCESS)) {
                throw new MsgException("银盛云商服3.0商户签约申请请求失败, {}", respEntity.getSubMsg());
            }
            //保存费率
            channelFee(0.38d,0.38d, channel, mcs.getMerchantCode());
        }

        JSONObject businessData = JSON.parseObject(respEntity.getBusinessData());
        mcs.getExtra().putAll(businessData);
        mcsService.updateById(mcs);

        Notice notice = new Notice(1, -1, mbi.getUserId());
        String uniqueKey = "YS_QY" + System.currentTimeMillis();
        String title = "电子协议签约通知";
        String content = "尊敬的客户您好，请点此通知完成签约意愿授权。请注意，同意授权后，支付通道才会进行商户资料审核，否则会一直等待审核。";
        String url = businessData.getString("signUrl");
        notice.setUniqueKey(uniqueKey);
        notice.setNoticeCode(uniqueKey);
        notice.setTitle(title);
        notice.setUrl(url);
        notice.setDesc(content);
        noticeService.save(notice);

        generalPushUtil.sendAllPlatByAlias(Collections.singletonList(mbi.getUserId()), title, content, "1");
    }

    @Override
    public void callback(JSONObject callback, Integer channel) throws Exception {
//        String signContent = SignUtils.getSignContent(callback);
//        String signStr = callback.getString("sign");
//        Sign sign = SecureUtil.sign(SignAlgorithm.SHA256withRSA, null, ysConfig.getOldPubKey());
//        boolean verify;
//
//        try {
//            verify = sign.verify(signContent.getBytes(StandardCharsets.UTF_8), Base64.decode(signStr));
//        } catch (Exception e) {
//            log.info("回调验签异常");
//            e.printStackTrace();
//            verify = true;
//        }
//
//        if (!verify) {
//            log.info("银盛云商服3.0回调验签失败");
//            throw new MsgException("银盛云商服3.0回调验签失败");
//        }
        String bizContent = callback.getString("bizContent");
        Notify notifyData = JSON.parseObject(bizContent, Notify.class);

        switch (notifyData.getNotifyType()) {
            case Notify.TYPE_MERC_APPLY:
                // 资料确认通知
                Notify.Cust cust = notifyData.getCust();
                cust.setStatus(notifyData.getStatus());
                auditResultHandle(cust,channel);
                break;
            case Notify.TYPE_MERC_SIGN:
                // 签约变更通知
                Notify.Auth auth = notifyData.getAuth();
                auth.setStatus(notifyData.getStatus());
                signResultHandle(auth,channel);
                break;
            case Notify.TYPE_MERC_CHANGE:
                // 商户资料变更通知
            case Notify.TYPE_MERC_RATE_CHANGE:
                // 商户费率变更通知
                Notify.Change change = notifyData.getChange();
                change.setStatus(notifyData.getStatus());
//                editResultHandle(change);
                break;
            case Notify.TYPE_MERC_REPORT:
                // 报备通知
                Notify.Report report = notifyData.getReport();
                report.setStatus(notifyData.getStatus());
                collectSubMerId(report,channel);
                break;
        }
    }

    @Override
    public void auditResult(String userId) {

    }

    public void preCheck(String userId, Integer channel) {
        MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByUserId(userId);
        LambdaQueryWrapper<MerchantChannelStatus> qWrapper = Wrappers.lambdaQuery();
        qWrapper.eq(MerchantChannelStatus::getMerchantCode, mbi.getMerchantCode());
        qWrapper.eq(MerchantChannelStatus::getVirChannelFlag, Account.CHANNEL_TYPE_D1);
        MerchantChannelStatus existD1 = mcsService.getOne(qWrapper);

        if (existD1 != null && !MerchantChannelStatus.AUDIT_STATUS_SUCCESS.equals(existD1.getStatus()) && !MerchantChannelStatus.AUDIT_STATUS_SIGNED.equals(existD1.getStatus()) && !MerchantChannelStatus.AUDIT_STATUS_WAITING_SIGN.equals(existD1.getStatus())) {
            throw new MsgException("当前D1通道存在未进件完成的的进件数据，不允许进件银盛");
        }
        //TODO 非营业执照商户同一结算人仅可申请两次实时到账
        if (MERCH_TYPE_MICRO.equals(mbi.getMerchantType())) {
            int ysCount = accountMapper.selectYSAuditSmallCount(mbi.getUserId());
            if (ysCount >= 2) {
                MsgException.throwException("非营业执照商户同一结算人仅可申请两次实时到账");
            }
        }

        qWrapper.clear();
        qWrapper.eq(MerchantChannelStatus::getMerchantCode, mbi.getMerchantCode());
        qWrapper.eq(MerchantChannelStatus::getVirChannelFlag, "D0");
        MerchantChannelStatus existD0 = mcsService.getOne(qWrapper);

        if (existD0 == null) {
            qWrapper.clear();
            qWrapper.eq(MerchantChannelStatus::getMerchantCode, mbi.getMerchantCode());
            qWrapper.isNull(MerchantChannelStatus::getChannel);
            existD0 = mcsService.getOne(qWrapper);
        }

        if (existD0 != null) {
            existD0 = mcsService.getByIdLock(existD0.getId());

            if (existD0.getStatus().equals(MerchantChannelStatus.AUDIT_STATUS_REJECT)) {
                return;
            }

            if (existD0.getStatus().equals(MerchantChannelStatus.AUDIT_STATUS_EXAMINING) && existD0.getThirdStatus().equals(MerchantChannelStatus.AUDIT_THIRD_STATUS_AUDITING)) {
                throw new MsgException("当前商户已经在后台审核中");
            }

            // 此处先将进件状态锁住
            existD0.setChannel(channel);
            mcsService.saveOrUpdate(existD0);
        }
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public void step1(String userId, Integer channel) {
        MercInfo mercInfo = combineBaseInfo(userId, channel);
        RespEntity req = ysServiceV3.req(ReqMethod.addCustInfoApply, (JSONObject) JSONObject.toJSON(mercInfo), channel);
        String subCode = req.getSubCode();

        if (!Objects.equals(subCode, YsConfigV3.BIZ_SUCCESS)) {
            throw new MsgException(req.getSubMsg());
        }

        preCheck(userId, channel);
        MerchantChannelStatus mcs = new MerchantChannelStatus();
        MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByUserId(userId);
        mcs.setMerchantCode(mbi.getMerchantCode());
        mcs.setChannel(channel);
        mcs = mcsService.getOne(new QueryWrapper<>(mcs));

        if (mcs == null) {
            mcs = new MerchantChannelStatus();
            mcs.setMerchantCode(mcs.getMerchantCode());
            mcs.setChannel(channel);
        }

        JSONObject extra = mcs.getExtra();
        extra.putAll(JSON.parseObject(req.getBusinessData()));
        mcs.setApplicationId(extra.getString("sysFlowId"));
        mcs.setThirdStatus(MerchantChannelStatus.AUDIT_THIRD_STATUS_AUDITING);
        mcs.setInterfaceVersion(YsConfigV3.INTERFACE_VERSION);
        mcsService.saveOrUpdate(mcs);

        AccountDTO accountDTO = accountService.getRealAccount(userId, Account.CHANNEL_TYPE_D1);

        IdCard legalIdCard = idCardService.getLegalIdCard(userId);
        //upstreamInfoService.save(mbi, legalIdCard, accountDTO.getIdcard(), accountDTO.getBankCard(), 4);
    }

    private MercInfo combineBaseInfo(String userId, Integer channel) {
        CombineMercInfo combineMercInfo;
        if (channel.equals(4)){
            combineMercInfo = mercAuditListener.getMercInfo(userId, Account.CHANNEL_TYPE_D0);
        }else {
            combineMercInfo = mercAuditListener.getMercInfo(userId, Account.CHANNEL_TYPE_D1);
        }

        LambdaQueryWrapper<MerchantBaseInfo> qWrapper = Wrappers.lambdaQuery();
        qWrapper.eq(MerchantBaseInfo::getUserId, userId);
        MerchantBaseInfo mbi = mbiService.getOne(qWrapper);

        MercInfo mercInfo = new MercInfo();
        CustInfo custInfo = new CustInfo();
        mercInfo.setCustInfo(custInfo);
        //商户基本信息
        if ("1".equals(mbi.getMerchantType())) {
            custInfo.setMercName(mbi.getAlias());
        }else {
            custInfo.setMercName(mbi.getMerchantName());
        }
        custInfo.setMercShortName(mbi.getAlias());

        switch (mbi.getMerchantType()) {
            case MerchantBaseInfo.MERCH_TYPE_MICRO:
                custInfo.setMercType("2");
                break;
            case MerchantBaseInfo.MERCH_TYPE_INDIVIDUAL:
                custInfo.setMercType("3");
                break;
            case MerchantBaseInfo.MERCH_TYPE_COMPANY:
                custInfo.setMercType("4");
                break;
            default:
                throw new MsgException("暂未找到用户类型");
        }

        MccReflect ysMccReflect = reflectService.getYsMccReflect(mbi.getMcc());
        custInfo.setMccCd(mbi.getMcc());
        custInfo.setContactMail("chaozhanggui2022@163.com");
        custInfo.setCusMgrNm("蔡祥");
        //区分D0、D1
        if (channel.equals(4)) {
            custInfo.setNotifyUrl(YsConfigV3.AUDIT_NOTIFY_URL);
            custInfo.setAgtMercId(ysConfigV3.getAgentNo());
        }else {
            custInfo.setNotifyUrl(YsConfigV3.AUDIT_NOTIFY_URL_D1);
            custInfo.setAgtMercId(ysConfigV3.getAgentNoD1());
        }
//        custInfo.setRemark("测试商户");

        //法人基本信息
        CrpInfo crpInfo = new CrpInfo();
        mercInfo.setCrpInfo(crpInfo);
        IdCard legalIdCard = combineMercInfo.getLegalIdCard();

        crpInfo.setCrpCertNo(legalIdCard.getCertNo());
        crpInfo.setCrpCertType("00");
        crpInfo.setCertBgn(legalIdCard.getCertStartTime().replace("-", ""));
        if (legalIdCard.getCertEndTime().equals("长期")) {
            crpInfo.setCertExpire("29991231");
        } else {
            crpInfo.setCertExpire(legalIdCard.getCertEndTime().replace("-", ""));
        }

        crpInfo.setCrpNm(legalIdCard.getCertName());
        BankCard bankCard = combineMercInfo.getBankCard();
        crpInfo.setCrpPhone(bankCard.getPhone());

        //银行卡相关
        StlAccInfo stlAccInfo = new StlAccInfo();
        mercInfo.setStlAccInfo(stlAccInfo);

        // 非法人授权信息
        if (!legalIdCard.getCertNo().equals(combineMercInfo.getSettleIdCard().getCertNo())) {
            IdCard idCard = combineMercInfo.getSettleIdCard();
            PersonInfo authInfo = new PersonInfo();
            authInfo.setName(idCard.getCertName());
            authInfo.setCertType("00");
            authInfo.setCertNo(idCard.getCertNo());
            authInfo.setCertBgn(idCard.getCertStartTime().replace("-", ""));

            if (idCard.getCertEndTime().equals("长期")) {
                authInfo.setCertExpire("29991231");
            } else {
                authInfo.setCertExpire(idCard.getCertEndTime().replace("-", ""));
            }

            crpInfo.setAuthInfo(authInfo);

            stlAccInfo.setIsUncrpSett("Y");
            stlAccInfo.setBankMobile(bankCard.getPhone());
            stlAccInfo.setOpenCertNo(idCard.getCertNo());
        }

        stlAccInfo.setStlAccNm(bankCard.getBankHolder());
        stlAccInfo.setStlAccNo(bankCard.getBankCardNo());
        stlAccInfo.setBankSubCode(bankCard.getContactLine());
        RegionCodeYs ysRegionCode = regionReflectService.getYsRegionCode(bankCard);
        // 由于联行号地址存在对应不上的问题，所以这里还是将地区信息给带上
        stlAccInfo.setBankProince(ysRegionCode.getProvinceCode());
        stlAccInfo.setBankCity(ysRegionCode.getCityCode());
        if (bankCard.getAccountType().equals(BankCard.ACCOUNT_TYPE_PRIVATE)) {
            stlAccInfo.setStlAccType("11");
        } else {
            stlAccInfo.setStlAccType("21");
        }
        //营业执照相关
        BusInfo busInfo = new BusInfo();
        mercInfo.setBusInfo(busInfo);

        if (!mbi.getMerchantType().equals(MerchantBaseInfo.MERCH_TYPE_MICRO)) {
            busInfo.setBusNm(mbi.getBussAuthName());
            busInfo.setBusNo(mbi.getBussAuthNum());
            if (mbi.getBussAuthStartTime() == null || mbi.getBussAuthEndTime() == null){
               throw new MsgException("营业执照日期有误");
            }
            busInfo.setBusCertBgn(mbi.getBussAuthStartTime().replace("年","")
                        .replace("月", "").replace("日", ""));
            busInfo.setBusCertExpire(mbi.getBussAuthEndTime().replace("年","")
                        .replace("月", "").replace("日", ""));
            busInfo.setBusAddr(mbi.getBussAuthAddress());
            busInfo.setBusCertType("19");
        } else {
            busInfo.setBusAddr(mbi.getProvince() + mbi.getCity() + mbi.getDistrict() + mbi.getAddress());
        }

        RegionCodeYs regionData = regionReflectService.getYsRegionCode(mbi.getProvince(), mbi.getCity(), mbi.getDistrict());
        busInfo.setBusProviceCode(regionData.getProvinceCode());
        busInfo.setBusCityCode(regionData.getCityCode());
        busInfo.setBusAreaCode(regionData.getAreaCode());

        return mercInfo;
    }

    /**
     * 入网申请流水 sysFlowId
     * 备注 note
     * 客户号id custId
     * 入网状态 status
     */
    public void auditResultHandle(Notify.Cust cust, Integer channel) {
        String status = cust.getStatus();
        String sysFlowId = cust.getSysFlowId();
        MerchantChannelStatus mcs = new MerchantChannelStatus();
        mcs.setApplicationId(sysFlowId);
        mcs.setChannel(channel);
        mcs = mcsService.getOne(new QueryWrapper<>(mcs));
        mcs.setThirdStatus(status);
        mcs.getExtra().putAll((JSONObject) JSON.toJSON(cust));

        switch (status) {
            case YsConfigV3.STATUS_SUCCESS:
                mcs.setAuditSuccessTime(new Date());
                mcsService.updateById(mcs);
                sign(mcs,channel);
                break;
            case YsConfigV3.STATUS_REFUSE:
                List<String> excludeStatus = Arrays.asList(MerchantChannelStatus.AUDIT_STATUS_REJECT, MerchantChannelStatus.AUDIT_STATUS_SUCCESS);
                MerchantChannelStatus finalMcs = mcs;
                boolean returnFlag = excludeStatus.stream().anyMatch(s -> s.equals(finalMcs.getStatus()));
                if (returnFlag) {
                    return;
                }
                MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByMerchantCode(mcs.getMerchantCode());
                String note = cust.getNote();
                mcs.setRemark(note);
                mcs.setStatus(MerchantChannelStatus.AUDIT_STATUS_REJECT);
                mcsService.updateById(mcs);
                mercAuditListener.onFail(mbi.getUserId(), mcs, note);
                break;
            case YsConfigV3.STATUS_TO_MANUAL:
                List<String> excludeStatus2 = Arrays.asList(MerchantChannelStatus.AUDIT_STATUS_SUCCESS, MerchantChannelStatus.AUDIT_STATUS_ARTIFICIAL_EXAMINING);
                MerchantChannelStatus finalMcs2 = mcs;
                boolean returnFlag2 = excludeStatus2.stream().anyMatch(s -> s.equals(finalMcs2.getStatus()));
                if (returnFlag2) {
                    return;
                }
                mcs.setStatus(MerchantChannelStatus.AUDIT_STATUS_ARTIFICIAL_EXAMINING);
                mcsService.updateById(mcs);
                break;
        }
    }
    public void step2(String userId, Integer channel) {
        MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByUserId(userId);
        List<MerchantImage> miList = miService.getListOfMerch(userId, Account.CHANNEL_TYPE_D0);
        MerchantChannelStatus mcs = new MerchantChannelStatus();
        mcs.setChannel(channel);
        mcs.setMerchantCode(mbi.getMerchantCode());
        mcs = mcsService.getOne(new QueryWrapper<>(mcs));

        if (mcs == null) {
            throw new MsgException("无法上传图片，无法确认进件信息");
        }

        for (MerchantImage mi : miList) {
            imageUpload(mi.getPhotoType(), mi.getPicUrl(), mcs.getApplicationId());
        }
    }
    public void step3(String userId, Integer channel) {
        MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByUserId(userId);
        MerchantChannelStatus mcs = mcsService.getByMerchantCode(mbi.getMerchantCode(), channel);

        if (mcs == null) {
            throw new MsgException("无法确认进件信息");
        }

        JSONObject param = new JSONObject();
        param.put("auditFlag", "Y");
        param.put("sysFlowId", mcs.getApplicationId());

        RespEntity respEntity = ysServiceV3.req(ReqMethod.auditCustInfoApply, param, channel);

        JSONObject bizContent = JSON.parseObject(respEntity.getBusinessData());
        mcs.getExtra().putAll(bizContent);
        String status = bizContent.getString("status");

        if (status == null) {
            log.error("银盛云商服3.0进件异常, {}", respEntity.getSubMsg());
            return;
        }

        mcs.setThirdStatus(status);
        switch (status) {
            case YsConfigV3.STATUS_SUCCESS:
                // 这里不做任何处理，交给回调操作，防止数据错乱
                break;
            case YsConfigV3.STATUS_REFUSE:
                mcs.setRemark(respEntity.getSubMsg());
                mcs.setStatus(MerchantChannelStatus.AUDIT_STATUS_REJECT);
                mcsService.updateById(mcs);
                mercAuditListener.onFail(mbi.getUserId(), mcs, respEntity.getSubMsg());
                break;
            case YsConfigV3.STATUS_TO_MANUAL:
                mcs.setRemark(respEntity.getSubMsg());
                mcs.setStatus(MerchantChannelStatus.AUDIT_STATUS_ARTIFICIAL_EXAMINING);
                mcsService.updateById(mcs);
                break;
        }
        mcsService.updateById(mcs);
    }
    private void imageUpload(String photoType, String imgUrl, String flowId) {
        int count = 0;
        while (count < 3) {
            count++;
            String relPhotoType = imgTypeTransform(photoType);
            if (photoType == null) {
                throw new MsgException("缺少图片类型");
            }

            RespEntity respEntity = ysServiceV3.reqUpload(ReqMethod.upload, relPhotoType, imgUrl, flowId);

            if (!Objects.equals(respEntity.getSubCode(), YsConfigV3.BIZ_SUCCESS)) {
                log.info("第{}次上传失败：{}", count, respEntity.getSubMsg());
            } else {
                if (photoType.equals(MerchantImage.ImageType.BANK_CARD_FRONT)) {
                    imageUpload(MerchantImage.ImageType.BANK_CARD_BACK, imgUrl, flowId);
                }

                return;
            }
        }

        throw new MsgException("图片多次上传失败");
    }
    public String imgTypeTransform(String imageType) {
        if (imageType == null) {
            throw new MsgException("图片类型不能为空");
        }

        switch (imageType) {
            case MerchantImage.ImageType.SHOP_FRONT_DOOR:
                return "A006";
            case MerchantImage.ImageType.STORE_INTERIOR_PHOTO:
                return "A007";
            case MerchantImage.ImageType.CASH_DESK_PHOTO:
                return "A008";
            case MerchantImage.ImageType.ACCOUNT_PERMITS:
                return "A011";
            case MerchantImage.ImageType.BUSINESS_LICENSE:
                return "A001";
            case MerchantImage.ImageType.IDCARD_FRONT:
                return "A003";
            case MerchantImage.ImageType.IDCARD_BACK:
                return "A002";
            case MerchantImage.ImageType.BANK_CARD_FRONT:
                return "A004";
            case MerchantImage.ImageType.BANK_CARD_BACK:
                return "A005";
            case MerchantImage.ImageType.SETTLE_IDCARD_FRONT:
                return "A013";
            case MerchantImage.ImageType.SETTLE_IDCARD_BACK:
                return "A014";
            case MerchantImage.ImageType.NON_LEG_SETTLE_AUTH:
                return "B005";
            case MerchantImage.ImageType.CHANGE_FORM:
                return "B008";
            case MerchantImage.ImageType.CASH_DESK_WITH_PERSON:
                return "B009";
        }

        return null;
    }
    public void signResultHandle(Notify.Auth authData, Integer channel) {
        QueryWrapper<MerchantChannelStatus> qWrapper = Wrappers.query();
        qWrapper.eq("extra ->> '$.authId'", authData.getAuthId());
        qWrapper.eq("channel", channel);
        MerchantChannelStatus mcs = mcsService.getOne(qWrapper);
        mcs = mcsService.getByIdLock(mcs.getId());

        mcs.getExtra().putAll((JSONObject) JSON.toJSON(authData));

        MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByMerchantCode(mcs.getMerchantCode());

        String status = authData.getStatus();
        switch (status) {
            case YsConfigV3.STATUS_SUCCESS:
                if (mcs.getStatus().equals(MerchantChannelStatus.AUDIT_STATUS_SUCCESS)) {
                    return;
                }

                AccountDTO accountDTO = accountService.getRealAccount(mbi.getUserId(), Account.CHANNEL_TYPE_D0);
                String mercId = authData.getMercId();
                mcs.setMerchantId(mercId);
                mcs.setStatus(MerchantChannelStatus.AUDIT_STATUS_SUCCESS);
                mcs.setAuditSuccessTime(new Date());
                if (mbi.getMerchantType().equals(MerchantBaseInfo.MERCH_TYPE_MICRO)) {
                    mcs.getExtra().put("mercCnm", accountDTO.getIdcard().getCertName());
                } else {
                    mcs.getExtra().put("mercCnm", mbi.getBussAuthName());
                }
                mcsService.updateById(mcs);
                if (channel == 4) {
                    openOnlinePay(mcs);
                }
                //暂时用手动进件
//                mercAuditListener.onSuccess(mbi.getUserId(), mcs);
                //向小程序里加入商家
                handler.createStore(mcs);
//                //银盛再次报备
//                JSONObject bizContentMap = new JSONObject();
//                bizContentMap.put("channelId", "CUPS_WECHAT");
//                bizContentMap.put("mercId", mercId);
//                bizContentMap.put("appletId", "wxc2bb94c0ddda1032");
//                ysServiceV3.req(ReqMethod.appIdAddOrUpdate, bizContentMap);
                break;
            case YsConfigV3.STATUS_REFUSE:
                String note1 = authData.getNote();
                mcs.setRemark(note1);
                mcs.setStatus(MerchantChannelStatus.AUDIT_STATUS_REJECT);
                mcsService.updateById(mcs);
                mercAuditListener.onFail(mbi.getUserId(), mcs, note1);
                break;
            case YsConfigV3.STATUS_FAIL:
                String note2 = authData.getNote();
                mcs.setRemark(note2);
                mcs.setStatus(MerchantChannelStatus.AUDIT_STATUS_REJECT);
                mcsService.updateById(mcs);
                mercAuditListener.onFail(mbi.getUserId(), mcs, note2);
                break;
            case YsConfigV3.STATUS_SIGN_REFUSE:
                List<String> excludeStatus = Arrays.asList(MerchantChannelStatus.AUDIT_STATUS_REJECT, MerchantChannelStatus.AUDIT_STATUS_SUCCESS);
                MerchantChannelStatus finalMcs = mcs;
                boolean returnFlag = excludeStatus.stream().anyMatch(s -> s.equals(finalMcs.getStatus()));
                if (returnFlag) {
                    return;
                }
                String note = authData.getNote();
                mcs.setRemark(note);
                mcs.setStatus(MerchantChannelStatus.AUDIT_STATUS_REJECT);
                mcsService.updateById(mcs);
                mercAuditListener.onFail(mbi.getUserId(), mcs, note);
                break;
        }
    }
//    public void editResultHandle(Notify.Change changeResult) {
//        String status = changeResult.getStatus();
//
//        MercChangeRecord entity = mcrService.get(changeResult.getChangeSysFlowId(), 4);
//
//        if (entity == null && !Objects.equals(entity.getStatus(), MercChangeRecord.Status.AUDITING.getValue())) {
//            return;
//        }
//
//        if (YsConfigV3.STATUS_SUCCESS.equals(status)) {
//            // 变更成功
//            entity.setStatus(MercChangeRecord.Status.SUCCESS.getValue());
//            mcrService.updateById(entity);
//
//            if (MercChangeRecord.Type.BASE.getValue().equals(entity.getChangeType())) {
//                // 基本信息变更完成
//                successChangeBaseInfo(entity, entity.getUserId() + "");
//            } else if (MercChangeRecord.Type.ACCOUNT.getValue().equals(entity.getChangeType())) {
//                // 结算卡变更完成
//                successChangeSettlement(entity, entity.getUserId() + "");
//            } else if (MercChangeRecord.Type.RATE.getValue().equals(entity.getChangeType())) {
//                // 费率变更完成
//                successChangeRate(entity, entity.getBaseInfo().getUserId());
//            } else if (MercChangeRecord.Type.CARD.getValue().equals(entity.getChangeType())) {
//                // TODO 证件补充, 云商服3.0没有该功能
//            }
//        }
//
//        if (YsConfigV3.STATUS_REFUSE.equals(status)) {
//            // 变更失败
//            entity.setStatus(MercChangeRecord.Status.REFUSE.getValue());
//            entity.setRemark(changeResult.getNote());
//            mcrService.updateById(entity);
//
//            if (MercChangeRecord.Type.BASE.getValue().equals(entity.getChangeType())) {
//                // 基本信息变更失败
//                failChangeBaseInfo(changeResult.getNote(), entity.getUserId() + "");
//            } else if (MercChangeRecord.Type.ACCOUNT.getValue().equals(entity.getChangeType())) {
//                // 结算卡变更失败
//                failChangeBankCard(changeResult.getNote(), entity.getUserId() + "");
//            } else if (MercChangeRecord.Type.RATE.getValue().equals(entity.getChangeType())) {
//                // 费率变更失败
//                failChangeRate(changeResult.getNote(), entity.getUserId() + "");
//            } else if (MercChangeRecord.Type.CARD.getValue().equals(entity.getChangeType())) {
//                // TODO 证件补充, 云商服3.0没有该功能
//            }
//        }
//    }
    @Override
    public void openOnlinePay(MerchantChannelStatus mcs) {
        try {
            JSONObject param = new JSONObject();
            param.put(YsConstant.MERC_ID, mcs.getMerchantId());
            param.put("option", "ON");
            param.put("rateFee", "0.38");
            param.put("rateBottom", "1");
            ysServiceV3.req(ReqMethod.openOnlinePay, param, mcs.getChannel());
        } catch (Exception e) {
            log.error("云商服3.0开通线上D0接口报错: {}", e.getMessage());
        }
    }

    public void collectSubMerId(Notify.Report report, Integer channel) {
        List<Notify.ThirdMerc> thridMercList = report.getThridMercList();

        if (thridMercList == null || thridMercList.isEmpty()) {
            return;
        }

        String mercId = report.getMercId();
        MerchantChannelStatus mcs = mcsService.getByMerchantId(mercId);

        LambdaQueryWrapper<SubMerchant> qWrapper = Wrappers.lambdaQuery();
        qWrapper.eq(SubMerchant::getMerchantId, mercId);
        smService.remove(qWrapper);

        for (Notify.ThirdMerc item : thridMercList) {
            String status = item.getApprSts();
            String thridMercId = item.getThridMercId();
            String reportChannel = item.getReportChannel();

            SubMerchant subMerchant = new SubMerchant();
            subMerchant.setChannelTypeId(String.valueOf(channel));

            String flagName = "";
            String typeName = "";

            if (reportChannel.contains("POS")) {
                continue;
            }

            if (reportChannel.contains("WECHAT")) {
                subMerchant.setSubMchType("WX");
                flagName = "微信";
            }

            if (reportChannel.contains("ALIPAY")) {
                subMerchant.setSubMchType("ZFB");
                flagName = "支付宝";
            }

            if (reportChannel.contains("NUCC")) {
                thridMercId += "_NUCC";
                typeName = "网联";
            }

            if (reportChannel.contains("CUPS")) {
                thridMercId += "_CUPS";
                typeName = "银联";
            }

            if (Objects.equals("03", status)) {
                LambdaQueryWrapper<UserApp> qWrapper2 = Wrappers.lambdaQuery();
                qWrapper2.eq(UserApp::getMerchantCode, mcs.getMerchantCode());
                qWrapper2.eq(UserApp::getUserType, "promoter");
                UserApp userApp = userAppMapper.selectOne(qWrapper2);

                String pushMsg = "D0通道" + flagName + typeName + "报备失败，请联系客服进行处理";
                sxfMerAuditHandler.sendNotice(userApp, "银收客审核通知", pushMsg, mcs.getApplicationId());
            }

            if (Objects.equals("00", status)) {
                subMerchant.setMerchantId(mercId);
                subMerchant.setStatus(status);
                subMerchant.setSubMchId(thridMercId);
                subMerchant.setRemark(item.getRemark());
                try {
                    smService.save(subMerchant);
                } catch (Exception ignored) {
                    // 插入报错不处理
                }
            }
        }
    }
    @Override
    public void report(MerchantChannelStatus mcs, Integer channel) {
        if (mcs == null) {
            return;
        }

        if (!mcs.getChannel().equals(channel)) {
            return;
        }

        String result = "";

        try {
            reportWxNucc(mcs);
        } catch (Exception e) {
            result += e.getMessage() + "\n";
        }

        try {
            reportWxCups(mcs);
        } catch (Exception e) {
            result += e.getMessage() + "\n";
        }

        try {
            reportAliNucc(mcs);
        } catch (Exception e) {
            result += e.getMessage() + "\n";
        }

        try {
            reportAliCups(mcs);
        } catch (Exception e) {
            result += e.getMessage();
        }

        if (result.length() > 0) {
            throw new MsgException(result);
        }
    }
    /**
     * 微信网联报备
     */
    public void reportWxNucc(MerchantChannelStatus mcs) {
        JSONObject param = new JSONObject();
        String merchantId = mcs.getMerchantId();
        param.put(YsConstant.MERC_ID, merchantId);
        param.put("reportChannel", "NUCC_WECHAT");

        RespEntity req = ysServiceV3.req(ReqMethod.sweepReport, param, Integer.valueOf(merchantId));
        if (!Objects.equals(req.getSubCode(), YsConfigV3.BIZ_SUCCESS)) {
            throw new MsgException("微信网联报备异常，" + req.getSubMsg());
        }
    }

    /**
     * 微信银联报备
     */
    public void reportWxCups(MerchantChannelStatus mcs) {
        JSONObject param = new JSONObject();
        String merchantId = mcs.getMerchantId();
        param.put(YsConstant.MERC_ID, merchantId);
        param.put("reportChannel", "CUPS_WECHAT");

        RespEntity req = ysServiceV3.req(ReqMethod.sweepReport, param, Integer.valueOf(merchantId));
        if (!Objects.equals(req.getSubCode(), YsConfigV3.BIZ_SUCCESS)) {
            throw new MsgException("微信银联报备异常，" + req.getSubMsg());
        }
    }

    /**
     * 支付宝网联报备
     */
    public void reportAliNucc(MerchantChannelStatus mcs) {
        JSONObject param = new JSONObject();
        String merchantId = mcs.getMerchantId();
        param.put(YsConstant.MERC_ID, merchantId);
        param.put("reportChannel", "NUCC_ALIPAY");

        RespEntity req = ysServiceV3.req(ReqMethod.sweepReport, param, Integer.valueOf(merchantId));
        if (!Objects.equals(req.getSubCode(), YsConfigV3.BIZ_SUCCESS)) {
            throw new MsgException("支付宝网联报备异常，" + req.getSubMsg());
        }
    }

    /**
     * 支付宝银联报备
     */
    public void reportAliCups(MerchantChannelStatus mcs) {
        JSONObject param = new JSONObject();
        String merchantId = mcs.getMerchantId();
        param.put(YsConstant.MERC_ID, merchantId);
        param.put("reportChannel", "CUPS_ALIPAY");

        RespEntity req = ysServiceV3.req(ReqMethod.sweepReport, param, Integer.valueOf(merchantId));
        if (!Objects.equals(req.getSubCode(), YsConfigV3.BIZ_SUCCESS)) {
            throw new MsgException("支付宝银联报备异常，" + req.getSubMsg());
        }
    }
    @Override
    public void reportAgain(MerchantChannelStatus mcs, Integer channel){
        if (mcs == null) {
            return;
        }

        if (!mcs.getChannel().equals(channel)) {
            return;
        }

        String result = "";

        try {
            reportAgainWxNucc(mcs);
        } catch (Exception e) {
            result += e.getMessage() + "\n";
        }

        try {
            reportAgainWxCups(mcs);
        } catch (Exception e) {
            result += e.getMessage() + "\n";
        }

        try {
            reportAgainAliNucc(mcs);
        } catch (Exception e) {
            result += e.getMessage() + "\n";
        }

        try {
            reportAgainAliCups(mcs);
        } catch (Exception e) {
            result += e.getMessage();
        }

        if (result.length() > 0) {
            throw new MsgException(result);
        }
    }

    /**
     * 微信网联重新报备
     */
    public void reportAgainWxNucc(MerchantChannelStatus mcs) {
        JSONObject param = new JSONObject();
        String merchantId = mcs.getMerchantId();
        param.put(YsConstant.MERC_ID, merchantId);
        param.put("reportChannel", "NUCC_WECHAT");

        RespEntity req = ysServiceV3.req(ReqMethod.reportAgain, param, Integer.valueOf(merchantId));
        if (!Objects.equals(req.getSubCode(), YsConfigV3.BIZ_SUCCESS)) {
            throw new MsgException("微信网联报备异常，" + req.getSubMsg());
        }
    }
//    /**
//     * 默认传值，无效可以传空字符串
//     *
//     * @param merchantName 商户名称
//     * @param merchantId   商编
//     * @param legalName    法人、管理人名称
//     * @param bussAuthName 营业名称,
//     *                     eg: 营业执照名称，简称：商户简称
//     * @param bankHolder   持卡人
//     * @param bankCardNo   结算银行户名
//     * @param rateInfo     费率信息
//     * @param bizName      业务类型
//     * @return
//     */
//    public String getApplyImg(String merchantName, String merchantId, String legalName, String bussAuthName, String bankHolder,
//                              String bankCardNo, String rateInfo, String bizName) {
//        try {
//            ClassPathResource cpr = new ClassPathResource("templates/ys_change_table.xlsx");
//            Map<String, Object> param = new HashMap<>();
//            param.put("merchantName", merchantName);
//            param.put("merchantId", merchantId);
//            param.put("bussAuthName", bussAuthName);
//            param.put("bankHolder", bankHolder);
//            param.put("bankCardNo", bankCardNo);
//            param.put("rateInfo", rateInfo);
//            param.put("bizName", bizName);
//            param.put("legalName", legalName);
//
//            ByteArrayOutputStream baos = new ByteArrayOutputStream();
//            EasyExcel.write(baos).withTemplate(cpr.getInputStream()).sheet("Sheet1").doFill(param);
//
//            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
//
//            Properties props = System.getProperties();
//
//            Workbook wb = new Workbook();
//            wb.loadFromStream(bais);
//            wb.setCodeName("UTF-8");
//            Worksheet sheet = wb.getWorksheets().get(0);
//            //随机起一个名称
//            String property = props.getProperty("user.home");
//
//            String dirPath = property + File.separator + "apply";
//            File dir = new File(dirPath);
//            if (!dir.exists()) {
//                dir.mkdirs();
//            }
//            String uri = dirPath + File.separator + UUID.randomUUID() + ".jpg";
//            sheet.saveToImage(uri);
//            File file = new File(uri);
//            String imgUrl = OssOperatUtil.upload(file, "jpg");
//
//            log.info("商户变更申请表链接为：" + imgUrl);
//
//            file.delete();
//            return imgUrl;
//        } catch (IOException e) {
//            return null;
//        }
//
//    }

    /**
     * 微信银联重新报备
     */
    public void reportAgainWxCups(MerchantChannelStatus mcs) {
        JSONObject param = new JSONObject();
        String merchantId = mcs.getMerchantId();
        param.put(YsConstant.MERC_ID, merchantId);
        param.put("reportChannel", "CUPS_WECHAT");

        RespEntity req = ysServiceV3.req(ReqMethod.reportAgain, param, Integer.valueOf(merchantId));
        if (!Objects.equals(req.getSubCode(), YsConfigV3.BIZ_SUCCESS)) {
            throw new MsgException("微信银联报备异常，" + req.getSubMsg());
        }
    }

    /**
     * 支付宝网联重新报备
     */
    public void reportAgainAliNucc(MerchantChannelStatus mcs) {
        JSONObject param = new JSONObject();
        String merchantId = mcs.getMerchantId();
        param.put(YsConstant.MERC_ID, merchantId);
        param.put("reportChannel", "NUCC_ALIPAY");

        RespEntity req = ysServiceV3.req(ReqMethod.reportAgain, param, Integer.valueOf(merchantId));
        if (!Objects.equals(req.getSubCode(), YsConfigV3.BIZ_SUCCESS)) {
            throw new MsgException("支付宝网联报备异常，" + req.getSubMsg());
        }
    }

    /**
     * 支付宝银联重新报备
     */
    public void reportAgainAliCups(MerchantChannelStatus mcs) {
        JSONObject param = new JSONObject();
        String merchantId = mcs.getMerchantId();
        param.put(YsConstant.MERC_ID, merchantId);
        param.put("reportChannel", "CUPS_ALIPAY");

        RespEntity req = ysServiceV3.req(ReqMethod.reportAgain, param,Integer.valueOf(merchantId));
        if (!Objects.equals(req.getSubCode(), YsConfigV3.BIZ_SUCCESS)) {
            throw new MsgException("支付宝银联报备异常，" + req.getSubMsg());
        }
    }
    public void sendProtocolMsg(MerchantChannelStatus mcs) {
        MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByMerchantCode(mcs.getMerchantCode());
        if (!mcs.getStatus().equals(MerchantChannelStatus.AUDIT_STATUS_WAITING_SIGN)) {
            throw new MsgException("当前状态不能发送签约短信");
        }

        String signId = mcs.getExtra().getString("signId");
        if (StringUtils.isEmpty(signId)) {
            sign(mcs,mcs.getChannel());
            return;
        }

        JSONObject reqParam = new JSONObject();
        reqParam.put("signId", signId);
        reqParam.put("isSendConMsg", "1");

        RespEntity respEntity = ysServiceV3.req(ReqMethod.sendSmsOrEmailMsg, reqParam,mcs.getChannel());
        if (!Objects.equals(respEntity.getSubCode(), YsConfigV3.BIZ_SUCCESS)) {
            throw new MsgException("银盛云商服3.0商户签约短信请求失败, " + respEntity.getSubMsg());
        }

        JSONObject businessData = JSON.parseObject(respEntity.getBusinessData());
        mcs.getExtra().putAll(businessData);
        mcsService.updateById(mcs);

        Notice notice = new Notice(1, -1, mbi.getUserId());
        String uniqueKey = "YS_QY" + System.currentTimeMillis();
        String title = "电子协议签约通知";
        String content = "尊敬的客户您好，请点此通知完成签约意愿授权。请注意，同意授权后，支付通道才会进行商户资料审核，否则会一直等待审核。";
        String url = businessData.getString("signUrl");
        notice.setUniqueKey(uniqueKey);
        notice.setNoticeCode(uniqueKey);
        notice.setTitle(title);
        notice.setUrl(url);
        notice.setDesc(content);
        noticeService.save(notice);

        generalPushUtil.sendAllPlatByAlias(Collections.singletonList(mbi.getUserId()), title, content, "1");
    }
    /**
     * 变更结算卡
     * 一般不支持非法人结算卡变更
     */
    public void editAccountInfo(BankCardDTO bankCardDTO, Integer channel) {
//        MercChangeRecord entity = mcrService.get(userId, 4, MercChangeRecord.Type.ACCOUNT, MercChangeRecord.Status.EDIT);
//        if (entity == null) {
//            throw new MsgException("没有需要变更的信息");
//        }

//        BankCard bankCard = entity.getBankCardInfo();
//        IdCard idCard = entity.getIdCardInfo();

        MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByUserId(bankCardDTO.getUserId());

        MerchantChannelStatus mcs = mcsService.getByMerchantCode(mbi.getMerchantCode(), channel);

        RegionCodeYs ysRegionCode = regionReflectService.getYsRegionCode(bankCardDTO);
//        JSONObject ext = entity.getExt();
//        String settleType;
//        if (ext == null) {
//            settleType = Account.LEGAL_PRIVATE_LEGAL;
//        } else {
//            settleType = ext.getString("settleType");
//        }
//
//        if (idCard == null) {
//            AccountDTO accountDTO = accountService.getRealAccount(userId, AccountDTO.CHANNEL_TYPE_D0);
//            idCard = accountDTO.getIdcard();
//        }
        Account account = new Account();
        IdCard accountIdCard;
        if (4 == channel) {
            account.setUserId(bankCardDTO.getUserId()).setChannelType(Account.CHANNEL_TYPE_D0);
            account = accountService.getOne(new QueryWrapper<>(account));
            accountIdCard = idCardService.getAccountIdCard(bankCardDTO.getUserId(), Account.CHANNEL_TYPE_D0);
            JSONObject bak = account.getBak();
        }else {
            account.setUserId(bankCardDTO.getUserId()).setChannelType(Account.CHANNEL_TYPE_D1);
            account = accountService.getOne(new QueryWrapper<>(account));
            accountIdCard = idCardService.getAccountIdCard(bankCardDTO.getUserId(), Account.CHANNEL_TYPE_D1);
            JSONObject bak = account.getBak();
        }

        JSONObject param = new JSONObject();
        param.put(YsConstantV3.NOTIFY_URL, YsConfigV3.AUDIT_NOTIFY_URL);
        StlAccInfo stlAccInfo = new StlAccInfo();
        stlAccInfo.setIsSettInPlatAcc("N");
        stlAccInfo.setIsUncrpSett(account.getSettleType().startsWith(Account.SETTLE_TYPE_PRIVATE_ILLEGAL) ? "Y" : "N");
        stlAccInfo.setStlAccNo(bankCardDTO.getBankCardNo());
        stlAccInfo.setStlAccType(account.getSettleType().startsWith(Account.SETTLE_TYPE_CORPORATE) ? "21" : "11");
        stlAccInfo.setOpenCertNo(accountIdCard.getCertNo());
        stlAccInfo.setStlAccNm(bankCardDTO.getBankHolder());
        stlAccInfo.setBankSubCode(bankCardDTO.getContactLine());
        stlAccInfo.setBankMobile(bankCardDTO.getPhone());
        stlAccInfo.setBankProince(ysRegionCode.getProvinceCode());
        stlAccInfo.setBankCity(ysRegionCode.getCityCode());

        param.put("stlAccInfo", stlAccInfo);
        param.put(YsConstant.MERC_ID, mcs.getMerchantId());

//        String applyImg = entity.getChangeForm();

        RespEntity req = ysServiceV3.req(ReqMethod.changeMercStlAccInfo, param, channel);
        if (!YsConfigV3.BIZ_SUCCESS.equals(req.getSubCode())) {
            throw new MsgException(req.getSubMsg());
        }

        String businessData = req.getBusinessData();
        JSONObject bizData = JSON.parseObject(businessData);
        String changeSysFlowId = bizData.getString("changeSysFlowId");

//        entity.setApplicationId(changeSysFlowId);
//        entity.setStatus(MercChangeRecord.Status.AUDITING.getValue());

        if (bankCardDTO.getAccountType().equals(BankCard.ACCOUNT_TYPE_CORPORATE)) {
            // 对公结算需要上传开户许可证
            imageEditUpload(MerchantImage.ImageType.ACCOUNT_PERMITS, bankCardDTO.getLicenseUrl(), changeSysFlowId);
        } else {
            // 对私结算需要上传银行卡图片
            imageEditUpload(MerchantImage.ImageType.BANK_CARD_FRONT, bankCardDTO.getImgUrl(), changeSysFlowId);
        }

        // 非法人结算，传结算人的身份证图片
        if (Objects.equals(account.getSettleType(), Account.SETTLE_TYPE_PRIVATE_ILLEGAL)) {
            imageEditUpload(MerchantImage.ImageType.SETTLE_IDCARD_FRONT, accountIdCard.getImgPositive(), changeSysFlowId);
            imageEditUpload(MerchantImage.ImageType.SETTLE_IDCARD_BACK, accountIdCard.getImgNegative(), changeSysFlowId);
        }

        // 申请表
//        imageEditUpload(MerchantImage.ImageType.CHANGE_FORM, applyImg, changeSysFlowId);
//
//        log.debug("云商服3.0基本信息变更发起成功");
//        String title = "收银呗商户信息变更通知";
//        String remark = "D0结算信息变更已发起";
//
//        entity.setRemark(remark);
//        mcrService.saveOrUpdate(entity);
//
//        noticeService.saveSysNotice(userId, title, remark);
//        generalPushUtil.sendAllPlatByAlias(Collections.singletonList(userId), title, remark, "1");
    }
    /**
     * 变更基本信息
     */
//    public void editBaseInfo(String userId) {
//        MercChangeRecord entity = mcrService.get(userId, 4, MercChangeRecord.Type.BASE, MercChangeRecord.Status.EDIT);
//        if (entity == null) {
//            throw new MsgException("没有需要变更的信息");
//        }
//
//        MerchantBaseInfo baseInfo = entity.getBaseInfo();
//
//        MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByUserId(userId);
//
//        MerchantChannelStatus mcs = mcsService.getByMerchantCode(mbi.getMerchantCode(), 4);
//
//        JSONObject param = new JSONObject();
//        param.put("notifyUrl", YsConfigV3.AUDIT_NOTIFY_URL);
//        param.put(YsConstant.MERC_ID, mcs.getMerchantId());
//        if (baseInfo != null) {
//            JSONObject custInfo = new JSONObject();
//            custInfo.put("mercName", baseInfo.getMerchantName());
//            custInfo.put("mercShortName", baseInfo.getAlias());
//            // 其他属性暂不考虑
//            param.put("custInfo", custInfo);
//        }
//
//        IdCard legalCardInfo = entity.getLegalCardInfo();
//        if (legalCardInfo != null) {
//            JSONObject crpInfo = new JSONObject();
//            crpInfo.put("crpNm", legalCardInfo.getCertName());
//            crpInfo.put("certExpire", legalCardInfo.getCertEndTime().replace("-", ""));
//            param.put("crpInfo", crpInfo);
//        }
//
//        RespEntity req = ysServiceV3.req(ReqMethod.changeMercBaseInfo, param);
//        if (!YsConfigV3.BIZ_SUCCESS.equals(req.getSubCode())) {
//            throw new MsgException(req.getSubMsg());
//        }
//
//        String businessData = req.getBusinessData();
//        JSONObject bizData = JSON.parseObject(businessData);
//        String changeSysFlowId = bizData.getString("changeSysFlowId");
//
//        entity.setApplicationId(changeSysFlowId);
//        entity.setStatus(MercChangeRecord.Status.AUDITING.getValue());
//
//        if (legalCardInfo != null) {
//            int count = 3;
//            String errorMsg = null;
//            do {
//                RespEntity uploadPostImg = ysServiceV3.reqUpload(ReqMethod.uploadChangePic, "A002", legalCardInfo.getImgPositive(), changeSysFlowId);
//                if (!YsConfigV3.BIZ_SUCCESS.equals(uploadPostImg.getSubCode())) {
//                    errorMsg = uploadPostImg.getSubMsg();
//                    count--;
//                    continue;
//                }
//                break;
//            } while (count > 0);
//
//            if (count == 0) {
//                log.debug("基本信息变更失败，上传身份证正面异常，" + errorMsg);
//                String title = "收银呗商户信息变更通知";
//                String remark = "基本信息变更失败，上传图片正面异常，" + errorMsg;
//
//                entity.setRemark(remark);
//
//                noticeService.saveSysNotice(userId, title, remark);
//                generalPushUtil.sendAllPlatByAlias(Collections.singletonList(userId), title, remark, "1");
//                return;
//            }
//
//            count = 3;
//
//            do {
//                RespEntity uploadPostImg = ysServiceV3.reqUpload(ReqMethod.uploadChangePic, "A003", legalCardInfo.getImgNegative(), changeSysFlowId);
//                if (!YsConfigV3.BIZ_SUCCESS.equals(uploadPostImg.getSubCode())) {
//                    errorMsg = uploadPostImg.getSubMsg();
//                    count--;
//                    continue;
//                }
//                break;
//            } while (count > 0);
//
//            if (count == 0) {
//                log.debug("基本信息变更失败，上传身份证反面异常，" + errorMsg);
//                String title = "收银呗商户信息变更通知";
//                String remark = "基本信息变更失败，上传图片异常，" + errorMsg;
//
//                entity.setRemark(remark);
//
//                noticeService.saveSysNotice(userId, title, remark);
//                generalPushUtil.sendAllPlatByAlias(Collections.singletonList(userId), title, remark, "1");
//                return;
//            }
//
//            count = 3;
//            do {
//                RespEntity uploadPostImg = ysServiceV3.reqUpload(ReqMethod.uploadChangePic, "B008", blankPng, changeSysFlowId);
//                if (!YsConfigV3.BIZ_SUCCESS.equals(uploadPostImg.getSubCode())) {
//                    errorMsg = uploadPostImg.getSubMsg();
//                    count--;
//                    continue;
//                }
//                break;
//            } while (count > 0);
//
//            if (count == 0) {
//                log.debug("基本信息变更失败，上传身份证反面异常，" + errorMsg);
//                String title = "收银呗商户信息变更通知";
//                String remark = "基本信息变更失败，上传图片异常，" + errorMsg;
//
//                entity.setRemark(remark);
//
//                noticeService.saveSysNotice(userId, title, remark);
//                generalPushUtil.sendAllPlatByAlias(Collections.singletonList(userId), title, remark, "1");
//                return;
//            }
//        } else {
//            AccountDTO realAccount = accountService.getRealAccount(userId, Account.CHANNEL_TYPE_D0);
//            legalCardInfo = realAccount.getIdcard();
//        }
//
//        String bussAuthName = "简称：" + mbi.getAlias();
//        if (!mbi.getMerchantType().equals(MerchantBaseInfo.MERCH_TYPE_MICRO)) {
//            bussAuthName += mbi.getMerchantName() + ", " + bussAuthName;
//        }
//
//        String applyImg = getApplyImg(mbi.getMerchantName(), mcs.getMerchantId(), legalCardInfo.getCertName(), bussAuthName, ""
//                , "", "", "变更商户基本信息");
//
//        String picType = "B008";
//        RespEntity uploadPostImg = ysServiceV3.reqUpload(ReqMethod.uploadChangePic, picType, applyImg, changeSysFlowId);
//        if (!YsConfigV3.BIZ_SUCCESS.equals(uploadPostImg.getSubCode())) {
//            throw new MsgException(req.getSubMsg());
//        }
//
//        req = ysServiceV3.req(ReqMethod.changeMercStlAccInfo, param);
//        if (!YsConfigV3.BIZ_SUCCESS.equals(req.getSubCode())) {
//            throw new MsgException(req.getSubMsg());
//        }
//
//        mcrService.save(entity);
//        log.debug("云商服3.0基本信息变更发起成功");
//        String title = "收银呗商户信息变更通知";
//        String remark = "D0基本信息变更已发起";
//
//        entity.setRemark(remark);
//
//        noticeService.saveSysNotice(userId, title, remark);
//        generalPushUtil.sendAllPlatByAlias(Collections.singletonList(userId), title, remark, "1");
//    }
    private void imageEditUpload(String photoType, String imgUrl, String flowId) {
        int count = 0;
        while (count < 3) {
            count++;
            String relPhotoType = imgTypeTransform(photoType);
            if (relPhotoType == null) {
                throw new MsgException("缺少图片类型");
            }

            RespEntity respEntity = ysServiceV3.reqUpload(ReqMethod.uploadChangePic, relPhotoType, imgUrl, flowId);

            if (!Objects.equals(respEntity.getSubCode(), YsConfigV3.BIZ_SUCCESS)) {
                log.info("第{}次上传失败：{}", count, respEntity.getSubMsg());
            } else {
                if (photoType.equals(MerchantImage.ImageType.BANK_CARD_FRONT)) {
                    imageEditUpload(MerchantImage.ImageType.BANK_CARD_BACK, imgUrl, flowId);
                }

                return;
            }
        }

        throw new MsgException("图片多次上传失败");
    }

    /**
     * 修改费率
     */
//    public void editRate(String userId) {
//        MercChangeRecord entity = mcrService.get(userId, 4, MercChangeRecord.Type.RATE, MercChangeRecord.Status.EDIT);
//        if (entity == null) {
//            throw new MsgException("没有需要变更的信息");
//        }
//
//        MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByUserId(userId);
//        MerchantChannelStatus mcs = mcsService.getByMerchantCode(mbi.getMerchantCode(), 4);
//        MerchantRateNew rateInfo = entity.getRateInfo();
//
//        MerchantRateNewVO vo = Converter.INSTANCE.toVO(rateInfo);
//        MerchantRateNewVO.setRateValue(vo);
//
//        RateFeeInfo rateFeeInfo = new RateFeeInfo();
//        rateFeeInfo.setAliPayFee(new RateFeeDetail("0", vo.getAliRateValue().divide(BigDecimal.valueOf(100)).stripTrailingZeros().toPlainString(), "1"));
//        rateFeeInfo.setWxPayFee(new RateFeeDetail("0", vo.getWxRateValue().divide(BigDecimal.valueOf(100)).stripTrailingZeros().toPlainString(), "1"));
//        rateFeeInfo.setBank1debitPayFee(new RateFeeDetail("0", vo.getBankRateLargeValue().divide(BigDecimal.valueOf(100)).stripTrailingZeros().toPlainString(), "1", "999900"));
//        rateFeeInfo.setBank1creditPayFee(new RateFeeDetail("0", vo.getBankRateLargeValue().divide(BigDecimal.valueOf(100)).stripTrailingZeros().toPlainString(), "1", "999900"));
//        rateFeeInfo.setBank2debitPayFee(new RateFeeDetail("0", vo.getBankRateValue().divide(BigDecimal.valueOf(100)).stripTrailingZeros().toPlainString(), "1", "999900"));
//        rateFeeInfo.setBank2creditPayFee(new RateFeeDetail("0", vo.getBankRateValue().divide(BigDecimal.valueOf(100)).stripTrailingZeros().toPlainString(), "1"));
//        RateFeeDetail codeScanD0Fee = new RateFeeDetail("0", "0.10", "1");
//
//        JSONObject param = new JSONObject();
//        param.put("codeScanT1Fee", rateFeeInfo);
//        param.put("codeScanD0Fee", codeScanD0Fee);
//        param.put(YsConstant.MERC_ID, mcs.getMerchantId());
//        param.put("notifyUrl", YsConfigV3.AUDIT_NOTIFY_URL);
//
//        String rateInfoContent = "微信：" + rateFeeInfo.getWxPayFee().getRateFee() + "%; ";
//        rateInfoContent += "支付宝：" + rateFeeInfo.getAliPayFee().getRateFee() + "%; ";
//        rateInfoContent += "银联：关闭";
//
//        IdCard legalIdCard = idCardService.getLegalIdCard(userId);
//        if (legalIdCard == null) {
//            legalIdCard = idCardService.getAccountIdCard(userId, Account.CHANNEL_TYPE_D0);
//        }
//
//        String applyImg = getApplyImg(mbi.getMerchantName(), mcs.getMerchantId(), legalIdCard.getCertName(), "", "", "", rateInfoContent, "费率变更");
//
//
//        RespEntity req = ysServiceV3.req(ReqMethod.changeRate, param);
//        if (!YsConfigV3.BIZ_SUCCESS.equals(req.getSubCode())) {
//            throw new MsgException(req.getSubMsg());
//        }
//
//        entity.setStatus(MercChangeRecord.Status.AUDITING.getValue());
//
//        String businessData = req.getBusinessData();
//        JSONObject bizJSON = JSON.parseObject(businessData);
//        String changeSysFlowId = bizJSON.getString("changeSysFlowId");
//        entity.setApplicationId(changeSysFlowId);
//
//        RespEntity uploadPostImg = ysServiceV3.reqUpload(ReqMethod.uploadChangePic, "B008", applyImg, changeSysFlowId);
//        if (!YsConfigV3.BIZ_SUCCESS.equals(uploadPostImg.getSubCode())) {
//            throw new MsgException(req.getSubMsg());
//        }
//
//        mcrService.saveOrUpdate(entity);
//
//        log.debug("云商服3.0基本信息变更发起成功");
//        String title = "收银呗商户信息变更通知";
//        String remark = "D0费率变更已发起";
//
//        entity.setRemark(remark);
//
//        noticeService.saveSysNotice(userId, title, remark);
//        generalPushUtil.sendAllPlatByAlias(Collections.singletonList(userId), title, remark, "1");
//    }
    /**
     * 更新法人身份证
     * @param userId
     */
//    public void modifyLegalCard(String userId) {
//        MercChangeRecord mcr = mcrService.get(userId, CHANNEL_ID, MercChangeRecord.Type.CARD, MercChangeRecord.Status.EDIT);
//        MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByUserId(userId);
//        MerchantChannelStatus mcs = mcsService.getByMerchantCode(mbi.getMerchantCode(), CHANNEL_ID);
//        IdCard legalCardInfo = mcr.getLegalCardInfo();
//
//        CrpInfo crpInfo = new CrpInfo();
//        crpInfo.setCrpNm(legalCardInfo.getCertName());
//        if ("长期".equals(legalCardInfo.getCertEndTime())) {
//            crpInfo.setCertExpire("29991231");
//        } else {
//            crpInfo.setCertExpire(legalCardInfo.getCertEndTime().replace("-", ""));
//        }
//
//        JSONObject param = new JSONObject();
//        param.put(YsConstantV3.MERC_ID, mcs.getMerchantId());
//        param.put(YsConstantV3.CRP_NAME, YsConfigV3.AUDIT_NOTIFY_URL);
//        param.put("crpInfo", crpInfo);
//
//        try {
//            RespEntity req = ysServiceV3.req(ReqMethod.changeMercBaseInfo, param);
//
//            String businessData = req.getBusinessData();
//            JSONObject bizJson = JSON.parseObject(businessData);
//            String changeSysFlowId = bizJson.getString("changeSysFlowId");
//
//            // 上传法人身份证正面图片
//            ysServiceV3.reqUpload(ReqMethod.uploadChangePic, "A002", legalCardInfo.getImgPositive(), changeSysFlowId);
//            // 上传法人身份证反面图片
//            ysServiceV3.reqUpload(ReqMethod.uploadChangePic, "A003", legalCardInfo.getImgNegative(), changeSysFlowId);
//            // 上传变更表图片
//            ysServiceV3.reqUpload(ReqMethod.uploadChangePic, "B008", mcr.getChangeForm(), changeSysFlowId);
//
//            mcr.setApplicationId(changeSysFlowId);
//            mcr.setStatus(MercChangeRecord.Status.AUDITING);
//            mcrService.updateById(mcr);
//        } catch (Exception e) {
//            mcr.setApplicationId("SYB_" + UUID.randomUUID().toString().replace("-", ""));
//            mcr.setRemark(e.getMessage());
//            mcr.setStatus(MercChangeRecord.Status.REFUSE);
//            mcrService.updateById(mcr);
//
//            JSONObject ext = new JSONObject();
//            ext.put("remark", e.getMessage());
//            editResultService.onFail(CHANNEL_ID, mcr.getApplicationId(), ext);
//        }
//    }
    /**
     * 更新结算身份证
     * @param userId
     */
//    public void modifyAccCard(String userId) {
//        MercChangeRecord mcr = mcrService.get(userId, CHANNEL_ID, MercChangeRecord.Type.CARD, MercChangeRecord.Status.EDIT);
//        MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByUserId(userId);
//        MerchantChannelStatus mcs = mcsService.getByMerchantCode(mbi.getMerchantCode(), CHANNEL_ID);
//        IdCard idCard = mcr.getIdCardInfo();
//        BankCard bankCard = mcr.getBankCardInfo();
//
//
//        StlAccInfo stlAccInfo = new StlAccInfo();
//        stlAccInfo.setStlAccNm(idCard.getCertName());
//        stlAccInfo.setIsUncrpSett("Y");
//        stlAccInfo.setIsSettInPlatAcc("N");
//        stlAccInfo.setStlAccType("11");
//        stlAccInfo.setOpenCertNo(idCard.getCertNo());
//        stlAccInfo.setBankSubCode(bankCard.getContactLine());
//        stlAccInfo.setBankMobile(bankCard.getPhone());
//
//        RegionCodeYs regionCodeYs = regionCodeYsService.getRegionData(bankCard.getBranchProvince(), bankCard.getBranchCity(), bankCard.getBranchArea());
//        stlAccInfo.setBankProince(regionCodeYs.getProvinceCode());
//        stlAccInfo.setBankCity(regionCodeYs.getCityCode());
//
//
//        JSONObject param = new JSONObject();
//        param.put(YsConstantV3.MERC_ID, mcs.getMerchantId());
//        param.put(YsConstantV3.CRP_NAME, YsConfigV3.AUDIT_NOTIFY_URL);
//        param.put("stlAccInfo", stlAccInfo);
//
//        try {
//            RespEntity req = ysServiceV3.req(ReqMethod.changeMercBaseInfo, param);
//
//            String businessData = req.getBusinessData();
//            JSONObject bizJson = JSON.parseObject(businessData);
//            String changeSysFlowId = bizJson.getString("changeSysFlowId");
//
//            // 上传银行卡卡号面图片
//            ysServiceV3.reqUpload(ReqMethod.uploadChangePic, "A004", bankCard.getImgUrl(), changeSysFlowId);
//            // 上传银行卡背面图片
//            ysServiceV3.reqUpload(ReqMethod.uploadChangePic, "A005", bankCard.getImgUrl(), changeSysFlowId);
//            // 上传结算人身份证正面图片
//            ysServiceV3.reqUpload(ReqMethod.uploadChangePic, "A013", idCard.getImgPositive(), changeSysFlowId);
//            // 上传结算人身份证反面图片
//            ysServiceV3.reqUpload(ReqMethod.uploadChangePic, "A014", idCard.getImgNegative(), changeSysFlowId);
//            // 上传变更表图片
//            ysServiceV3.reqUpload(ReqMethod.uploadChangePic, "B008", mcr.getChangeForm(), changeSysFlowId);
//
//            mcr.setApplicationId(changeSysFlowId);
//            mcr.setStatus(MercChangeRecord.Status.AUDITING);
//            mcrService.updateById(mcr);
//        } catch (Exception e) {
//            mcr.setApplicationId("SYB_" + UUID.randomUUID().toString().replace("-", ""));
//            mcr.setRemark(e.getMessage());
//            mcr.setStatus(MercChangeRecord.Status.REFUSE);
//            mcrService.updateById(mcr);
//
//            JSONObject ext = new JSONObject();
//            ext.put("remark", e.getMessage());
//            editResultService.onFail(CHANNEL_ID, mcr.getApplicationId(), ext);
//        }
//    }
    /**
     * 修改营业执照
     * @param userId    用户ID
     */
//    public void editBusLicense(String userId) {
//        MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByUserId(userId);
//        MerchantChannelStatus mcs = mcsService.getByMerchantCode(mbi.getMerchantCode(), 1);
//
//        Assert.notNull(mcs, "未获取到进件信息");
//        if (!Objects.equals(mcs.getChannel(), 1)) {
//            throw new MsgException("未获取到进件信息");
//        }
//
//        MercChangeRecord mcRecord = mcrService.get(userId, 1, MercChangeRecord.Type.BLL);
//        MerchantBaseInfo newMbi = mcRecord.getBaseInfo();
//
//        JSONObject param = new JSONObject();
//        BusInfo busInfo = new BusInfo();
//        busInfo.setBusNm(newMbi.getBussAuthName());
//        busInfo.setBusCertExpire(newMbi.getBussAuthEndTime().replace("-", ""));
//        busInfo.setBusAddr(newMbi.getBussAuthAddress());
//        busInfo.setRegAddr(newMbi.getBussAuthAddress());
//
//        param.put("busInfo", busInfo);
//
//        RespEntity req = ysServiceV3.req(ReqMethod.changeMercBaseInfo, param);
//
//    }
    /**
     * 查询进件结果
     * @param mcs
     */
    public void auditResult(MerchantChannelStatus mcs,Integer channel) {
        if (mcs == null) {
            return;
        }

        if (!MerchantChannelStatus.AUDIT_STATUS_EXAMINING.equals(mcs.getStatus())
                && !MerchantChannelStatus.AUDIT_STATUS_ARTIFICIAL_EXAMINING.equals(mcs.getStatus())) {
            return;
        }

        String sysFlowId = mcs.getExtra().getString("sysFlowId");
        if (StringUtils.isEmpty(sysFlowId)) {
            return;
        }

        RespEntity respEntity = ysServiceV3.req(ReqMethod.queryCustApply, new JSONObject().fluentPut("sysFlowId", sysFlowId),channel);
        if (!Objects.equals(respEntity.getSubCode(), YsConfigV3.BIZ_SUCCESS)) {
            throw new MsgException("银盛云商服3.0商户信息状态确认失败: {}", respEntity.getSubMsg());
        }

        Notify.Cust cust = JSON.parseObject(respEntity.getBusinessData(), Notify.Cust.class);
        auditResultHandle(cust,channel);
    }

//    public void result(String sysFlowId){
//        RespEntity respEntity = ysServiceV3.req(ReqMethod.queryCustApply, new JSONObject().fluentPut("sysFlowId", sysFlowId));
//        if (!Objects.equals(respEntity.getSubCode(), YsConfigV3.BIZ_SUCCESS)) {
//            throw new MsgException("银盛云商服3.0商户信息状态确认失败: {}", respEntity.getSubMsg());
//        }
//    }

    /**
     * 查询签约结果，该操作作为商户最终状态的判断
     * @param userId    用户id
     */
    public void signResult(String userId, Integer channel) {
        MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByUserId(userId);
        MerchantChannelStatus mcs = mcsService.getByMerchantCode(mbi.getMerchantCode(), channel);
        if (mcs == null) {
            return;
        }

        if (!MerchantChannelStatus.AUDIT_STATUS_WAITING_SIGN.equals(mcs.getStatus())) {
            return;
        }

        String authId = mcs.getExtra().getString("authId");
        if (StringUtils.isEmpty(authId)) {
            return;
        }

        JSONObject reqParam = new JSONObject();
        reqParam.put("authId", authId);

        RespEntity respEntity = ysServiceV3.req(ReqMethod.queryAuthInfo, reqParam,channel);
        if (!Objects.equals(respEntity.getSubCode(), YsConfigV3.BIZ_SUCCESS)) {
            throw new MsgException("银盛云商服3.0商户签约状态请求失败, {}", respEntity.getSubMsg());
        }

        signResultHandle(JSON.parseObject(respEntity.getBusinessData(), Notify.Auth.class),channel);
    }
    /**
     * 查询商户变更结果
     * @param userId 用户id
     */
//    public void editResult(String userId) {
//        MercChangeRecord entity = mcrService.get(userId, 4, null, MercChangeRecord.Status.AUDITING);
//        if (entity == null) {
//            return;
//        }
//
//        JSONObject param = new JSONObject();
//        param.put("changeSysFlowId", entity.getApplicationId());
//        RespEntity respEntity = ysServiceV3.req(ReqMethod.queryCustChange, param);
//
//        if (!Objects.equals(respEntity.getSubCode(), YsConfigV3.BIZ_SUCCESS)) {
//            log.error("银盛云商服商户变更结果查询失败：{}", respEntity.getSubMsg());
//            return;
//        }
//
//        String businessData = respEntity.getBusinessData();
//
//        Notify.Change changeResult = JSON.parseObject(businessData, Notify.Change.class);
//
//        editResultHandle(changeResult);
//    }

//    public void editResultHandle(Notify.Change changeResult) {
//        String status = changeResult.getStatus();
//
//        MercChangeRecord entity = mcrService.get(changeResult.getChangeSysFlowId(), 4);
//
//        if (entity == null && !Objects.equals(entity.getStatus(), MercChangeRecord.Status.AUDITING.getValue())) {
//            return;
//        }
//
//        if (YsConfigV3.STATUS_SUCCESS.equals(status)) {
//            // 变更成功
//            entity.setStatus(MercChangeRecord.Status.SUCCESS.getValue());
//            mcrService.updateById(entity);
//
//            if (MercChangeRecord.Type.BASE.getValue().equals(entity.getChangeType())) {
//                // 基本信息变更完成
//                successChangeBaseInfo(entity, entity.getUserId() + "");
//            } else if (MercChangeRecord.Type.ACCOUNT.getValue().equals(entity.getChangeType())) {
//                // 结算卡变更完成
//                successChangeSettlement(entity, entity.getUserId() + "");
//            } else if (MercChangeRecord.Type.RATE.getValue().equals(entity.getChangeType())) {
//                // 费率变更完成
//                successChangeRate(entity, entity.getBaseInfo().getUserId());
//            } else if (MercChangeRecord.Type.CARD.getValue().equals(entity.getChangeType())) {
//                // TODO 证件补充, 云商服3.0没有该功能
//            }
//        }
//
//        if (YsConfigV3.STATUS_REFUSE.equals(status)) {
//            // 变更失败
//            entity.setStatus(MercChangeRecord.Status.REFUSE.getValue());
//            entity.setRemark(changeResult.getNote());
//            mcrService.updateById(entity);
//
//            if (MercChangeRecord.Type.BASE.getValue().equals(entity.getChangeType())) {
//                // 基本信息变更失败
//                failChangeBaseInfo(changeResult.getNote(), entity.getUserId() + "");
//            } else if (MercChangeRecord.Type.ACCOUNT.getValue().equals(entity.getChangeType())) {
//                // 结算卡变更失败
//                failChangeBankCard(changeResult.getNote(), entity.getUserId() + "");
//            } else if (MercChangeRecord.Type.RATE.getValue().equals(entity.getChangeType())) {
//                // 费率变更失败
//                failChangeRate(changeResult.getNote(), entity.getUserId() + "");
//            } else if (MercChangeRecord.Type.CARD.getValue().equals(entity.getChangeType())) {
//                // TODO 证件补充, 云商服3.0没有该功能
//            }
//        }
//    }
    public void channelFee(Double WECHAT, Double ALIPAY, Integer channel, String merchantCode){
        JSONArray array = new JSONArray();
        Set<FeesSetVo> feesSet = new HashSet<>();
        FeesSetVo w = new FeesSetVo();
        w.setFeeCode("WECHAT");
        w.setFeeValue(WECHAT);
        array.add(w);

        FeesSetVo a = new FeesSetVo();
        a.setFeeCode("ALIPAY");
        a.setFeeValue(ALIPAY);
        array.add(a);

        feesSet.add(w);
        feesSet.add(a);
        MerchantChannelFee merchantChannelFee = new MerchantChannelFee();
        merchantChannelFee.setChannel(channel);
        merchantChannelFee.setMerchantCode(merchantCode);
        merchantChannelFee.setFeeStr(array.toJSONString());
        merchantChannelFee.setCreateTime(new Date());
        merchantChannelFeeMapper.insert(merchantChannelFee);
    }
}

