package com.jeequan.jeepay.agent.ctrl.applyment;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.components.mq.model.MchAuditMQ;
import com.jeequan.jeepay.components.mq.model.MchAuditThirdNotifyMQ;
import com.jeequan.jeepay.components.mq.vender.IMQSender;
import com.jeequan.jeepay.converter.MchInfoConverter;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.MchModifyApplyment;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.interfaces.paychannel.*;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.IsvChannelConfig;
import com.jeequan.jeepay.core.model.applyment.ApplymentBasicInfo;
import com.jeequan.jeepay.core.model.applyment.MchModifyApplymentModel;
import com.jeequan.jeepay.core.model.applyment.PaywayFee;
import com.jeequan.jeepay.core.model.oauth2.WxpayOauth2Params;
import com.jeequan.jeepay.core.model.params.hmpay.HmpayIsvsubMchParams;
import com.jeequan.jeepay.core.model.params.utmpay.UtmpayConfig;
import com.jeequan.jeepay.core.model.rqrs.msg.ChannelRetMsg;
import com.jeequan.jeepay.core.model.security.JeeUserDetails;
import com.jeequan.jeepay.core.utils.JeepayKit;
import com.jeequan.jeepay.core.utils.SeqKit;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.service.impl.*;
import com.jeequan.jeepay.thirdparty.channel.IsvFactory;
import com.jeequan.jeepay.thirdparty.service.ConfigContextQueryService;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * 进件管理
 *
 * @author terrfly
 * @date 2021/12/27 15:26
 */
@Slf4j
@RestController
@RequestMapping("/api/mchApplyments")
public class MchApplymentController extends CommonCtrl {

    @Autowired
    private IsvInfoService isvInfoService;
    @Autowired
    private MchApplymentService mchApplymentService;
    @Autowired
    private PayInterfaceConfigService payInterfaceConfigService;
    @Autowired
    private MchAppService mchAppService;
    @Autowired
    private IMQSender mqSender;
    @Autowired
    private RateConfigService rateConfigService;
    @Autowired
    private AgentConfigService agentConfigService;
    @Autowired
    private ConfigContextQueryService configContextQueryService;
    @Autowired
    private MchAppApplymentService mchAppApplymentService;
    @Autowired
    private MchModifyApplymentService modifyApplymentService;

    @Autowired
    private MchInfoConverter mchInfoConverter;

    @Autowired
    private MchPayInterfaceConfigService mchPayInterfaceConfigService;
    @Autowired
    private TransactionTemplate transactionTemplate;

    @PreAuthorize("hasAuthority('ENT_MCH_APPLYMENT_LIST')")
    @GetMapping
    public ApiRes list() {
        MchApplyment searchRecord = getObject(MchApplyment.class);
        Page<MchApplyment> page = getIPage(false);
        //联系电话解密
        if (StringUtils.isNotEmpty(searchRecord.getContactName())) {
            searchRecord.setContactPhone(SysConfigService.DB_ENCRYPT_SM4.encryptBase64(searchRecord.getContactName()));
        }
        // 扩展员仅查询自己的数据
        if (getCurrentUser().isEpUser()) {
            searchRecord.setEpUserId(getCurrentUser().getSysUser().getSysUserId());
        }
        // 可查看自己和全部下级服务商
        String currentAgentNo = getCurrentAgentNo();
        List<String> subAgentNoList = agentInfoService.queryAllSubAgentNo(currentAgentNo);
        if (CollectionUtil.isNotEmpty(subAgentNoList)) {
            searchRecord.setSubAgentNoList(subAgentNoList);
        }
        //searchRecord.setAgentNo(getCurrentAgentNo());
        Page<MchApplyment> result = mchApplymentService.selectMchApplyment(page, searchRecord);
        Optional.ofNullable(result).map(Page::getRecords)
                .ifPresent(itemList -> {
                    for (MchApplyment item : itemList) {
                        // 运营商端返回全部备注
                        item.setRemark(item.getAgtRemark());
                        item.setMgrRemark(null);
                        item.setMchRemark(null);
                    }
                });

        return ApiRes.page(result);
    }

    /**
     * 保存备注信息
     */
    @PreAuthorize("hasAuthority('ENT_MCH_APPLYMENT_LIST')")
    @PostMapping("/remark")
    public ApiRes remark() {
        String remark = getValString("remark");
        String applyId = getValString("applyId");

        Assert.notNull(applyId, "[applyId]不能为空");

        MchApplyment existData = mchApplymentService.getById(applyId);
        Assert.notNull(existData, "进件信息不存在");

        String existRemark = existData.getRemark();
        JSONObject remarkJSON = null;
        try {
            remarkJSON = JSON.parseObject(existRemark);
        } finally {
            if (remarkJSON == null) {
                remarkJSON = new JSONObject();
            }
            remarkJSON.put("agt", remark);
        }

        LambdaUpdateWrapper<MchApplyment> uWrapper = Wrappers.lambdaUpdate();
        uWrapper.eq(MchApplyment::getApplyId, applyId);
        uWrapper.set(MchApplyment::getRemark, remarkJSON.toJSONString());
        mchApplymentService.update(uWrapper);

        return ApiRes.ok();
    }

    /**
     * 标记风控 / 解除标记风控
     */
    @PreAuthorize("hasAuthority('ENT_MCH_APPLYMENT_LIST')")
    @PostMapping("/state")
    public ApiRes riskMark() {
        byte state = getValByte("state");
        String remark = getValString("remark");
        String applyId = getValString("applyId");

        Assert.notNull(state, "状态不能为空");


        Assert.notNull(applyId, "[applyId]不能为空");

        LambdaQueryWrapper<MchApplyment> qWrapper = Wrappers.lambdaQuery();
        qWrapper.eq(MchApplyment::getApplyId, applyId);
        MchApplyment existData = mchApplymentService.getOne(qWrapper);

        if (state != MchApplyment.STATE_WAIT_RISK
                && state != MchApplyment.STATE_WAIT_FREEZE
                && state != MchApplyment.STATE_WAIT_LOGOUT
                && state != MchApplyment.STATE_SUCCESS) {
            throw new BizException("状态参数[state]非法");
        }

        if (state == MchApplyment.STATE_SUCCESS) {
            if (existData.getState() != MchApplyment.STATE_WAIT_RISK
                    && existData.getState() != MchApplyment.STATE_WAIT_FREEZE
                    && existData.getState() != MchApplyment.STATE_WAIT_LOGOUT) {
                throw new BizException("当前商户状态不支持该操作");
            }
        }

        if (state == MchApplyment.STATE_WAIT_RISK) {
            if (existData.getState() != MchApplyment.STATE_SUCCESS) {
                throw new BizException("当前商户状态不支持该操作");
            }
        }

        if (state == MchApplyment.STATE_WAIT_FREEZE) {
            if (existData.getState() != MchApplyment.STATE_SUCCESS) {
                throw new BizException("当前商户状态不支持该操作");
            }
        }

        if (state == MchApplyment.STATE_WAIT_LOGOUT) {
            if (existData.getState() != MchApplyment.STATE_SUCCESS) {
                throw new BizException("当前商户状态不支持该操作");
            }
        }

        String existRemark = existData.getRemark();
        JSONObject remarkJSON = null;
        try {
            remarkJSON = JSON.parseObject(existRemark);
        } finally {
            if (remarkJSON == null) {
                remarkJSON = new JSONObject();
            }
            remarkJSON.put("agt", remark);
        }

        LambdaUpdateWrapper<MchApplyment> uWrapper = Wrappers.lambdaUpdate();
        uWrapper.eq(MchApplyment::getApplyId, applyId);
        uWrapper.set(MchApplyment::getRemark, remarkJSON.toJSONString());
        uWrapper.set(MchApplyment::getState, state);

        mchApplymentService.update(uWrapper);

        return ApiRes.ok();
    }

    @PreAuthorize("hasAuthority('ENT_MCH_APPLYMENT_GET_INFO')")
    @GetMapping("/channelState/{recordId}")
    public ApiRes channelState(@PathVariable("recordId") String recordId) {
        MchApplyment record = mchApplymentService.getById(recordId);

        if (record == null || !record.getAgentNo().equals(getCurrentAgentNo())) {
            throw new BizException("数据不存在");
        }

        // 只有 1 4 5 需要查询
        if (record.getRemainStep() != null && record.getRemainStep() > 0 && record.getState() == MchApplyment.STATE_AUDITING) {
            throw new BizException("商户数据提交请求中");
        }

        if (record.getState() != MchApplyment.STATE_AUDITING
                && record.getState() != MchApplyment.STATE_WAIT_VERIFY
                && record.getState() != MchApplyment.STATE_WAIT_SIGN
                && record.getState() != MchApplyment.STATE_FINISH_SIGN
                && record.getState() != MchApplyment.STATE_SUCCESS_NEED_SECOND_VERIFY) {
            throw new BizException("当前状态无需查询");
        }

        IIsvmchApplymentService applymentService = IsvFactory.getIsvMchApplymentService(JeepayKit.getIfCodeOrigin(record.getIfCode()));
        // 调起进件查询接口
        com.jeequan.jeepay.core.entity.MchApplyment applymentResultByRPC = applymentService.query(mchInfoConverter.toModel(record));
        MchApplyment applymentResult = new MchApplyment();
        mchInfoConverter.cp(applymentResultByRPC, applymentResult);

        // 当状态发生了变化时
        if (!record.getState().equals(applymentResult.getState())) {

            // 更新数据
            applymentResult.setApplyId(recordId);
            applymentResult.setLastApplyAt(new Date());
            mchApplymentService.updateById(applymentResult);

            boolean beforeSuccess = record.getState() == MchApplyment.STATE_SUCCESS || record.getState() == MchApplyment.STATE_SUCCESS_NEED_SECOND_VERIFY;
            boolean resultSuccess = applymentResult.getState() == MchApplyment.STATE_SUCCESS || applymentResult.getState() == MchApplyment.STATE_SUCCESS_NEED_SECOND_VERIFY;
            boolean successFlag = resultSuccess && !beforeSuccess;

            if (successFlag) {
                mchApplymentService.onApplymentSuccess(applymentResult.getApplyId());
                mqSender.send(MchAuditThirdNotifyMQ.build(recordId, MchAuditThirdNotifyMQ.TYPE_AUDIT));
            }
        }

        return ApiRes.ok(applymentResult);
    }


    /**
     * 查询合同最新信息
     **/
    @GetMapping("/channelSignInfo/{recordId}")
    public ApiRes channelSignInfo(@PathVariable("recordId") String recordId) {
        MchApplyment record = mchApplymentService.getById(recordId);

        if (record == null || !record.getAgentNo().equals(getCurrentAgentNo())) {
            throw new BizException("数据不存在");
        }

        // 放置签约额外参数（用于标识是否重签等）
        record.addExt("extSignInfo", getValString("extSignInfo"));
        // 调起接口
        IIsvmchApplymentService applymentService = IsvFactory.getIsvMchApplymentService(JeepayKit.getIfCodeOrigin(record.getIfCode()));
        return ApiRes.ok(applymentService.signInfo(mchInfoConverter.toModel(record)));
    }


    /**
     * 查询最新的微信开户意愿状态
     **/
    @GetMapping("/channelWxOpenInfo/{recordId}")
    public ApiRes channelWxOpenInfo(@PathVariable("recordId") String recordId) {
        MchApplyment record = mchApplymentService.getById(recordId);

        if (record == null || !record.getAgentNo().equals(getCurrentAgentNo())) {
            throw new BizException("数据不存在");
        }

        // 调起接口
        IIsvmchWxConfigService isvmchWxConfigService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(record.getIfCode()) + "IsvmchWxConfigService", IIsvmchWxConfigService.class);
        return ApiRes.ok(isvmchWxConfigService.wxOpenSignInfo(mchInfoConverter.toModel(record)));
    }

    /**
     * 查询最新的支付宝开户意愿状态
     **/
    @GetMapping("/channelAlipayOpenInfo/{recordId}")
    public ApiRes channelAlipayOpenInfo(@PathVariable("recordId") String recordId) {
        MchApplyment mRecord = mchApplymentService.getById(recordId);

        if (mRecord == null) {
            throw new BizException("数据不存在");
        }

        // 调起接口
        IIsvmchAlipayConfigService isvmchAlipayConfigService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(mRecord.getIfCode()) + "IsvmchAlipayConfigService", IIsvmchAlipayConfigService.class);

        return ApiRes.ok(isvmchAlipayConfigService.alipayOpenSignInfo(mchInfoConverter.toModel(mRecord)));
    }


    @PreAuthorize("hasAuthority('ENT_MCH_APPLYMENT_VIEW')")
    @GetMapping("/{recordId}")
    public ApiRes detail(@PathVariable("recordId") String recordId) {
        Byte originData = getValByteDefault("originData", CS.NO);
        MchApplyment mRecord;
        if (CS.NO == originData) {
            mRecord = mchApplymentService.getInfoById(recordId);
        } else {
            mRecord = mchApplymentService.getById(recordId);
        }
        if (mRecord == null || !mRecord.getAgentNo().equals(getCurrentAgentNo())) {
            return ApiRes.ok();
        }
        //返回数据增加名称字段
        if (StringUtils.isNotEmpty(mRecord.getIsvNo())) {
            IsvInfoEntity isvInfoEntity = isvInfoService.getById(mRecord.getIsvNo());
            if (isvInfoEntity != null){
                mRecord.setIsvName(isvInfoEntity.getIsvName());
            }
        }
        if (StringUtils.isNotEmpty(mRecord.getAgentNo())) {
            AgentInfo agentInfo = agentInfoService.getById(mRecord.getAgentNo());
            if (agentInfo != null){
                mRecord.setAgentNoName(agentInfo.getAgentName());
                mRecord.setAgentPhone(agentInfo.getContactTel());
            }
        }

        mRecord.setRemark(mRecord.getAgtRemark());
        mRecord.setMgrRemark(null);
        mRecord.setMchRemark(null);

        return ApiRes.ok(mRecord);
    }

    /**
     * 获取合并的进件信息
     **/
    @GetMapping("/mergeApplyDetailInfos/{mchNo}")
    public ApiRes mergeApplyDetailInfos(@PathVariable("mchNo") String mchNo) {

        // 指定记录中读取
        String fixApplyId = getValString("fixApplyId");

        // 当前进件页面操作的 ifCode
        String currentPageIfCode = getValString("currentPageIfCode");

        Class<ApplymentBasicInfo> applymentBasicInfoClass = ApplymentBasicInfo.getImplInfoClass(currentPageIfCode);
        Assert.notNull(applymentBasicInfoClass, "未知的通道编码[currentPageIfCode]");

        String mergeIfCode = "";

        List<MchApplyment> mergeList = mchApplymentService.list(MchApplyment.gw()
                .select(MchApplyment::getIfCode, MchApplyment::getApplyDetailInfo)
                .eq(StringUtils.isNotEmpty(fixApplyId), MchApplyment::getApplyId, fixApplyId)
                .eq(MchApplyment::getMchNo, mchNo));

        // 1. 获取到 读取到的列表数据
        for (MchApplyment info : mergeList) {
            mergeIfCode = info.getIfCode();
        }

        // 2. 包含fixApplyId 的话， 为：读取副本 操作   && 读取到的和 当前是同一个接口的
        if (StringUtils.isNotEmpty(fixApplyId) && !mergeList.isEmpty() && StringUtils.isNotEmpty(mergeIfCode) && mergeIfCode.equals(currentPageIfCode)) {
            JSONObject jsonObject;
            try {
                jsonObject = JSON.parseObject(mergeList.get(0).getApplyDetailInfo());
            } catch (Exception e) {
                jsonObject = new JSONObject();
            }
            jsonObject.put("paywayFeeList", null); // 清空费率信息
            jsonObject.put("uploadImgCache", null); // 清空： 上传图片的缓存信息
            return ApiRes.ok(jsonObject.toJavaObject(applymentBasicInfoClass));
        }

        JSONObject resultJson = new JSONObject();
        // 其他 智能读取 场景 。
        for (MchApplyment info : mergeList) {
            if (StringUtils.isNotEmpty(info.getApplyDetailInfo())) {
                JSONObject jsonObject;
                try {
                    jsonObject = JSON.parseObject(info.getApplyDetailInfo());
                } catch (Exception e) {
                    jsonObject = new JSONObject();
                }
                jsonObject.forEach(resultJson::putIfAbsent);
            }
        }

        // 点击智能读取，mcc，areacode，bankcode因不通用，可不用读取
        resultJson.put("mcc", null);
        resultJson.put("areaCode", null);
        resultJson.put("payWayFeeList", null);
        resultJson.put("uploadImgCache", null);

        return ApiRes.ok(resultJson.toJavaObject(applymentBasicInfoClass));
    }


    /**
     * 首次发起进件申请
     **/
    @PreAuthorize("hasAuthority('ENT_MCH_APPLYMENT_ADD')")
    @PostMapping
    public ApiRes firstApplyment() {
        String mchApplyNo = SeqKit.genMchApplyNo();
        MchApplyment mRecord = getObject(MchApplyment.class);
        if (mRecord.getRange() == 0 && StrUtil.isEmpty(mRecord.getAutoConfigMchAppId())) {
            MchAppEntity offlineApp = mchAppService.getOfflineApp(mRecord.getMchNo());
            Assert.notNull(offlineApp, "线下应用不存在或状态不正常");
            mRecord.setAutoConfigMchAppId(offlineApp.getAppId());
        }

        // 进件来源
        mRecord.setApplyPageType(CS.SYS_ROLE_TYPE.AGENT + "_" + getCurrentUser().getLoginType());

        // 通用检查项
        commonCheck(mRecord.getApplyId(), mRecord.getIsvNo(), mRecord.getMchNo(), mRecord.getIfCode(), true);

        boolean isTempData = mRecord.extv().getBooleanValue("isTempData"); // 是否保存为草稿

        MchInfo mchInfo = mchInfoService.getById(mRecord.getMchNo());

        if (MchInfo.isNotIsv(mchInfo)) {
            throw new BizException("请选择特约商户类型");
        }

        MchAppEntity mchApp = mchAppService.getById(mRecord.getAutoConfigMchAppId());
        Assert.notNull(mchApp, "请选择应用");

        PayInterfaceConfig config = payInterfaceConfigService.getByInfoIdAndIfCode(CS.SYS_ROLE_TYPE.ISV, mRecord.getIsvNo(), mRecord.getIfCode());

        MchPayInterfaceConfig mchConfig = mchInfoConverter.toMchConfig(config);
        mchConfig.setInfoType(CS.SYS_ROLE_TYPE.MCH_APPLYMENT);
        mchConfig.setInfoId(mchApplyNo);
        MchPayInterfaceConfig exitData = mchPayInterfaceConfigService.get(mchConfig.getInfoType(), mchConfig.getInfoId(), mchConfig.getIfCode());
        if (exitData != null) {
            mchConfig.setId(exitData.getId());
        }
        mchPayInterfaceConfigService.saveOrUpdate(mchConfig);

        mRecord.setPayInterfaceId(mchConfig.getId());

        // 校验商户的进件费率
        ApplymentBasicInfo applymentBasicInfo = JSON.parseObject(mRecord.getApplyDetailInfo(), ApplymentBasicInfo.class);
        if (applymentBasicInfo != null && applymentBasicInfo.getPaywayFeeList() != null) {
            rateConfigService.checkFeeByMch(mRecord.getMchNo(), "", mRecord.getIfCode(), applymentBasicInfo.getPaywayFeeList(), mchApp.getRange(), mchApp.getMccCode(), mRecord.getIsvNo());
        }

        // 设置名称
        mRecord.setIfName(payInterfaceDefineService.getById(mRecord.getIfCode()).getIfName());

        mRecord.setApplyId(mchApplyNo); //生成申请单号
        if (isTempData) { // 保存草稿
            mRecord.setState(com.jeequan.jeepay.core.entity.MchApplyment.STATE_SAVE);
        } else {
            // 是否在服务商进件允许的时间范围内
            if (agentConfigService.queryAgentApplymentTimeLimit(getCurrentAgentNo())) {
                throw new BizException("当前时间不允许进件，可进件时间范围为：" + agentConfigService.queryAgentApplymentTime(getCurrentAgentNo()));
            }
        }

        mRecord.setRemainStep((byte) 1);
        mRecord.setAgentNo(getCurrentAgentNo());     // 服务商号
        mRecord.setTopAgentNo(agentInfoService.queryTopAgentNo(getCurrentAgentNo()));    // 顶级服务商号

        mRecord.setEpUserId(mchInfo.getCreatedUid());
        mRecord.setCreatedUid(getCurrentUser().getSysUserId());
        mRecord.setCreatedBy(getCurrentUser().getSysUser().getRealname());


        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(@NonNull TransactionStatus transactionStatus) {
                mchApplymentService.saveOrUpdate(mRecord);
                rateConfigService.saveMchApplymentRate(mRecord);
            }
        });

        if (isTempData) { // 保存草稿
            return ApiRes.ok();
        }

        // 系统预审环节
        if (agentConfigService.queryAgentApplymentPreAudit(getCurrentAgentNo())) {
            MchApplyment auditTbMchApplyment = new MchApplyment();
            auditTbMchApplyment.setApplyId(mRecord.getApplyId());
            auditTbMchApplyment.setState(com.jeequan.jeepay.core.entity.MchApplyment.STATE_WAIT_PRE_AUDITING); //系统预审
            mchApplymentService.updateById(auditTbMchApplyment);
            return ApiRes.ok();
        }

        // 调起接口
        IIsvmchApplymentService isvmchApplymentService = IsvFactory.getIsvMchApplymentService(JeepayKit.getIfCodeOrigin(mRecord.getIfCode()));

        MchApplyment applymentResult = new MchApplyment();
        applymentResult.setApplyId(mRecord.getApplyId());

        // 调起进件接口
        try {
            com.jeequan.jeepay.core.entity.MchApplyment applymentResultByRPC = isvmchApplymentService.firstApplyment(mchInfoConverter.toModel(mRecord));
            mchInfoConverter.cp(applymentResultByRPC, applymentResult);

            // 更新数据
            applymentResult.setLastApplyAt(new Date());
            mchApplymentService.updateById(applymentResult);

        } catch (Exception e) {
            applymentResult.setLastApplyAt(new Date());
            applymentResult.setState(com.jeequan.jeepay.core.entity.MchApplyment.STATE_REJECT_WAIT_MODIFY);
            applymentResult.setApplyErrorInfo("[" + e.getMessage() + "]");
            mchApplymentService.updateById(applymentResult);
            log.info("进件失败：", e);
        }

        // 该状态为进件未完成状态，发送数据到消息队列中，
        if (applymentResult.getState() == MchApplyment.STATE_AUDITING_WAIT) {
            mqSender.send(MchAuditMQ.build(applymentResult.getApplyId()));
        }

        // 调起 进件接口

        // 返回了 审核中， 成功。 失败。 异常的情况认为是： 做失败处理。   异常最好在三方接口处理掉。

        // 审核中： 页面支持: 【查询最新状态】。

        // 驳回待修改：【查询最新状态】 【修改进件信息】 --》 修改接口、 补充进件、 重新进件 三选一。  根据上游渠道的不同调起的接口不一样。  接口内部消化吧。

        // 待验证、 待签约： 全部在备注信息中体现信息。 这种只能手动点击查询接口。  【查询最新状态】

        // 成功  修改进件信息（优先级低）

        // 失败 按照驳回待修改
        return ApiRes.ok();
    }

    /**
     * 修改再次提交进件资料
     **/
    @PreAuthorize("hasAuthority('ENT_MCH_APPLYMENT_EDIT')")
    @PutMapping("/{recordId}")
    public ApiRes rejectModify(@PathVariable("recordId") String recordId) {

        MchApplyment dbRecord = mchApplymentService.getById(recordId);

        if (dbRecord == null
                || (dbRecord.getState() != com.jeequan.jeepay.core.entity.MchApplyment.STATE_REJECT_WAIT_MODIFY && dbRecord.getState() != com.jeequan.jeepay.core.entity.MchApplyment.STATE_SAVE && dbRecord.getState() != MchApplyment.STATE_WAIT_PRE_AUDIT_REJECT)
                || !dbRecord.getAgentNo().equals(getCurrentAgentNo())) {
            throw new BizException("当前申请单状态不是待修改或草稿，无法继续。");
        }

        // 请求参数
        MchApplyment mRecord = getObject(MchApplyment.class);

        MchAppEntity mchApp = mchAppService.getById(mRecord.getAutoConfigMchAppId());
        Assert.notNull(mchApp, "未选择应用");

        // 通用检查项
        commonCheck(mRecord.getApplyId(), mRecord.getIsvNo(), mRecord.getMchNo(), mRecord.getIfCode(), false);

        boolean isTempData = mRecord.extv().getBooleanValue("isTempData"); // 是否保存为草稿

        // 校验商户的进件费率
        ApplymentBasicInfo applymentBasicInfo = JSON.parseObject(mRecord.getApplyDetailInfo(), ApplymentBasicInfo.class);
        if (applymentBasicInfo != null && applymentBasicInfo.getPaywayFeeList() != null) {
            rateConfigService.checkFeeByMch(mRecord.getMchNo(), "", mRecord.getIfCode(), applymentBasicInfo.getPaywayFeeList(), mchApp.getRange(), mchApp.getMccCode(), mRecord.getIsvNo());
        }

        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(@NonNull TransactionStatus transactionStatus) {
                mchApplymentService.saveOrUpdate(mRecord);
                rateConfigService.saveMchApplymentRate(mRecord);
            }
        });

        if (isTempData) {
            mRecord.setApplyId(recordId);
            mchApplymentService.updateById(mRecord);
            return ApiRes.ok();
        }

        // 是否在服务商进件允许的时间范围内
        if (agentConfigService.queryAgentApplymentTimeLimit(getCurrentAgentNo())) {
            throw new BizException("当前时间不允许进件，可进件时间范围为：" + agentConfigService.queryAgentApplymentTime(getCurrentAgentNo()));
        }

        MchInfo mchInfo = mchInfoService.getById(mRecord.getMchNo());

        if (MchInfo.isNotIsv(mchInfo)) {
            throw new BizException("请选择特约商户类型");
        }

        // 预审核失败的修改 --> 待审核
        if (dbRecord.getState() == MchApplyment.STATE_WAIT_PRE_AUDIT_REJECT) {

            mRecord.setApplyId(recordId);
            mRecord.setApplyErrorInfo("");
            mRecord.setState(MchApplyment.STATE_WAIT_PRE_AUDITING);
            mRecord.setUpdatedAt(new Date());
            mchApplymentService.updateById(mRecord);
            return ApiRes.ok();
        }

        // 更新DB数据， 重新发起申请
        mRecord.setState(MchApplyment.STATE_AUDITING); // 保存状态
        mRecord.setRemainStep((byte) 1);
        mRecord.setApplyErrorInfo(""); //清空错误信息
        mchApplymentService.update(mRecord, Wrappers.lambdaQuery(MchApplyment.class).eq(MchApplyment::getApplyId, recordId).in(MchApplyment::getState,
                Arrays.asList(com.jeequan.jeepay.core.entity.MchApplyment.STATE_SAVE, com.jeequan.jeepay.core.entity.MchApplyment.STATE_REJECT_WAIT_MODIFY)));
        rateConfigService.saveMchApplymentRate(mRecord);
        IIsvmchApplymentService isvMchApplymentService = IsvFactory.getIsvMchApplymentService(JeepayKit.getIfCodeOrigin(mRecord.getIfCode()));
        // 重新获取最新数据
        dbRecord = mchApplymentService.getById(recordId);

        PayInterfaceConfig config = payInterfaceConfigService.getByInfoIdAndIfCode(CS.SYS_ROLE_TYPE.ISV, mRecord.getIsvNo(), mRecord.getIfCode());

        MchPayInterfaceConfig mchConfig = mchInfoConverter.toMchConfig(config);
        mchConfig.setInfoType(CS.SYS_ROLE_TYPE.MCH_APPLYMENT);
        mchConfig.setInfoId(mRecord.getApplyId());
        MchPayInterfaceConfig exitData = mchPayInterfaceConfigService.get(mchConfig.getInfoType(), mchConfig.getInfoId(), mchConfig.getIfCode());
        if (exitData != null) {
            mchConfig.setId(exitData.getId());
        }
        mchPayInterfaceConfigService.saveOrUpdate(mchConfig);

        // 调起进件接口
        MchApplyment applymentResult = new MchApplyment();
        applymentResult.setApplyId(mRecord.getApplyId());

        // 调起进件接口
        try {
            com.jeequan.jeepay.core.entity.MchApplyment applymentResultByRPC = isvMchApplymentService.rejectModify(mchInfoConverter.toModel(dbRecord));
            BeanUtils.copyProperties(applymentResultByRPC, applymentResult);

            // 更新数据
            applymentResult.setApplyId(mRecord.getApplyId());
            applymentResult.setLastApplyAt(new Date());
            mchApplymentService.updateById(applymentResult);
        } catch (Exception e) {
            // 异步请求的异常
            applymentResult.setLastApplyAt(new Date());
            applymentResult.setState(com.jeequan.jeepay.core.entity.MchApplyment.STATE_REJECT_WAIT_MODIFY);
            applymentResult.setApplyErrorInfo("[" + e.getMessage() + "]");
            mchApplymentService.updateById(applymentResult);
            log.info("进件失败：", e);
        }

        // 该状态为进件未完成状态，发送数据到消息队列中，
        if (applymentResult.getState() == MchApplyment.STATE_AUDITING_WAIT) {
            mqSender.send(MchAuditMQ.build(applymentResult.getApplyId()));
        }

        return ApiRes.ok();
    }


    /**
     * 进件参数的配置
     **/
    @PostMapping("/appConfig/{applyId}/{mchAppId}")
    public ApiRes configApp(@PathVariable("applyId") String applyId, @PathVariable("mchAppId") String mchAppId) {

        MchApplyment tbMchApplyment = mchApplymentService.getById(applyId);
        if (tbMchApplyment == null || tbMchApplyment.getState() != MchApplyment.STATE_SUCCESS || !tbMchApplyment.getAgentNo().equals(getCurrentAgentNo())) {
            throw new BizException("进件不存在或状态不正确");
        }

        if (StringUtils.isEmpty(tbMchApplyment.getSuccResParameter())) {
            throw new BizException("不存在进件支付参数，请手动配置");
        }


        PayInterfaceConfig updateRecord = new PayInterfaceConfig();
        updateRecord.setIfParams(tbMchApplyment.getSuccResParameter());

        PayInterfaceConfig payInterfaceConfig = payInterfaceConfigService.getByInfoIdAndIfCode(CS.SYS_ROLE_TYPE.MCH_APP, mchAppId, tbMchApplyment.getIfCode());

        if (payInterfaceConfig != null) {
            updateRecord.setId(payInterfaceConfig.getId());
            payInterfaceConfigService.updateById(updateRecord);
        } else {

            updateRecord.setInfoType(CS.SYS_ROLE_TYPE.MCH_APP);
            updateRecord.setInfoId(mchAppId);
            updateRecord.setIfCode(tbMchApplyment.getIfCode());
            payInterfaceConfigService.save(updateRecord);

        }

        return ApiRes.ok();
    }


    /**
     * 查询其他配置信息（如支付目录， 渠道商微信公众号APPID）
     **/
    @GetMapping("/interfaceConfig/{applyId}")
    public ApiRes selectInterfaceConfig(@PathVariable("applyId") String applyId) {

        String isvNo = null;

        // 查询选择的OAuth2 信息
        String selectOauth2InfoId = null;

        // 根据appID 查询
//        if (getValByteDefault("applyIdConvertMchAppId", CS.NO) == CS.YES) {
//            MchInfo mchInfo = mchInfoService.getById(mchAppService.getById(applyId).getMchNo());
//            isvNo = mchInfo.getIsvNo();
//            selectOauth2InfoId = configContextQueryService.queryAgentOrIsvSelectOauth2InfoId(mchInfo, getValString("convertMchAppIfCode"));
//
//        } else {
//
//            MchApplyment tbMchApplyment = mchApplymentService.getById(applyId);
//            isvNo = tbMchApplyment.getIsvNo();
//            selectOauth2InfoId = configContextQueryService.queryAgentOrIsvSelectOauth2InfoId(tbMchApplyment.getAgentNo(), isvNo, tbMchApplyment.getIfCode());
//        }

        MchApplyment tbMchApplyment = mchApplymentService.getById(applyId);
        isvNo = tbMchApplyment.getIsvNo();
        selectOauth2InfoId = configContextQueryService.queryAgentOrIsvSelectOauth2InfoId(tbMchApplyment.getAgentNo(), isvNo, tbMchApplyment.getIfCode());

        String paySiteUrl = sysConfigService.getDBApplicationConfig().getPaySiteUrl();

        WxpayOauth2Params wxpayOauth2Params = configContextQueryService.queryOauth2Params(CS.SYS_ROLE_TYPE.ISV_OAUTH2, StringUtils.defaultIfEmpty(selectOauth2InfoId, isvNo), CS.IF_CODE.WXPAY, WxpayOauth2Params.class);

        JSONObject result = new JSONObject();
        String appId = "";
        String liteAppId = "";
        if (wxpayOauth2Params != null) {
            appId = wxpayOauth2Params.getAppId();
            liteAppId = wxpayOauth2Params.getLiteAppId();
        }
        result.put("paySiteUrl", paySiteUrl);
        result.put("wxAppId", appId);
        result.put("wxLiteAppId", liteAppId);
        return ApiRes.ok(result);
    }


    /**
     * 配置相关信息
     **/
    @PostMapping("/interfaceConfig/{applyId}/{mchAppId}")
    public ApiRes configInterfaceConfig(@PathVariable("applyId") String applyId, @PathVariable("mchAppId") String mchAppId) {

        String configType = getValStringRequired("configType"); // PAY_BASE_URL,  BIND_APP_ID,  SUBSCRIBE_APP_ID
        String configVal = getValStringRequired("configVal");

        MchAppEntity mchAppEntity = mchAppService.getById(mchAppId);
        String mchNo = mchAppEntity.getMchNo();

        String ifCode = null;
        String isvNo = null;

        // 商户应用的 渠道配置页面  && 传输过的是ifCode
        String appConfigModeAndIfCode = getValString("appConfigModeAndIfCode");

//        if (StringUtils.isNotEmpty(appConfigModeAndIfCode)) {
//            ifCode = appConfigModeAndIfCode;
//            isvNo = mchInfoService.getById(mchNo).getIsvNo();
//
//        } else { // 原逻辑
//
//            MchApplyment tbMchApplyment = mchApplymentService.getById(applyId);
//            ifCode = tbMchApplyment.getIfCode();
//            isvNo = tbMchApplyment.getIsvNo();
//        }

        MchApplyment tbMchApplyment = mchApplymentService.getById(applyId);
        ifCode = tbMchApplyment.getIfCode();
        isvNo = tbMchApplyment.getIsvNo();

        IIsvmchWxConfigService isvMchWxConfigService = IsvFactory.getIsvMchWxConfigService(JeepayKit.getIfCodeOrigin(ifCode));

        if ("PAY_BASE_URL".equals(configType)) {  // 微信支付目录

            return ApiRes.ok(isvMchWxConfigService.configPayBaseUrl(configVal, isvNo, mchNo, mchAppId, ifCode));

        }
        if ("QUERY".equals(configType)) {

            return ApiRes.ok(isvMchWxConfigService.queryConfiguredInfo(isvNo, mchNo, mchAppId, ifCode));

        } else if ("BIND_APP_ID".equals(configType)) { // 关联微信各种appId：

            return ApiRes.ok(isvMchWxConfigService.configBindAppId(configVal, isvNo, mchNo, mchAppId, ifCode));

        } else if ("SUBSCRIBE_APP_ID".equals(configType)) { // 支付成功关注公众号

            return ApiRes.ok(isvMchWxConfigService.configSubscribeAppId(configVal, isvNo, mchNo, mchAppId, ifCode));

        } else if ("MCH_SHORT_NAME".equals(configType)) {  // 修改商户名称

            return ApiRes.ok(isvMchWxConfigService.applyModifyMchShortName(configVal, isvNo, mchNo, mchAppId, ifCode));
        } else if ("MCH_APP_PUBLIC_KEY".equals(configType)) {   // 设置子商户公钥（目前仅盛付通使用）

            return ApiRes.ok(isvMchWxConfigService.applyModifyMchAppPublicKey(configVal, isvNo, mchNo, mchAppId, ifCode));

        } else if ("MCH_STORE_ADD".equals(configType)) {  // 门店配置（目前仅河马渠道使用）
            hmpaySubMchParamsModify(configVal, mchNo, mchAppId);
            return ApiRes.ok(ChannelRetMsg.confirmSuccess(null));

        } else if ("MCH_RATE_UPDATE".equals(configType)) { // 费率修改

            List<PaywayFee> list = JSON.parseArray(configVal, PaywayFee.class);
            return ApiRes.ok(isvMchWxConfigService.applyModifyMchRate(list, isvNo, mchNo, mchAppId, ifCode));
        }

        return ApiRes.customFail("没有[" + configType + "]配置");
    }


    /**
     * 预先校验当前商户是否可完成该通道的进件
     **/
    @GetMapping("/applyPreCheck/{mchNo}/{ifCode}")
    public ApiRes applyPreCheck(@PathVariable("mchNo") String mchNo, @PathVariable("ifCode") String ifCode) {
        String isvNo = getValStringRequired("isvNo");
        commonCheck(null, isvNo, mchNo, ifCode, true);
        return ApiRes.ok();
    }

    /**
     * 门店入驻
     **/
    @PostMapping("/storeApplyment/{storeId}/{state}/{recordId}")
    public ApiRes storeApplyment(@PathVariable("storeId") String storeId, @PathVariable("state") Byte state, @PathVariable("recordId") String recordId) {

        MchApplyment dbRecord = mchApplymentService.getById(recordId);

        if (dbRecord == null || dbRecord.getState() != MchApplyment.STATE_SUCCESS) {
            throw new BizException("当前申请单状态不是成功，无法继续。");
        }
        MchStore mchStore = mchStoreService.getById(storeId);
        if (mchStore == null) {
            throw new BizException("所选门店不存在。");
        }
        if (StringUtils.isEmpty(mchStore.getStoreOuterImg()) || StringUtils.isEmpty(mchStore.getStoreInnerImg()) ||
                mchStore.getAreaCode() == null || StringUtils.isEmpty(mchStore.getStoreLogo()) || StringUtils.isEmpty(mchStore.getContactPhone())) {
            throw new BizException("所选门店信息不完整，请先将门店信息填写完整再发起入驻申请。");
        }

        IIsvmchStoreApplymentService isvmchStoreApplymentService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(dbRecord.getIfCode()) + "MchStoreApplymentService", IIsvmchStoreApplymentService.class);

        // 调起进件接口
        com.jeequan.jeepay.core.entity.MchApplyment applymentResultByRPC = null;
        if (MchApplyment.STATE_AUDITING == state) {
            throw new BizException("门店正在审核中");
        }

        if (MchApplyment.STATE_REJECT_WAIT_MODIFY == state) {
            // 驳回待修改
            applymentResultByRPC = isvmchStoreApplymentService.storeApplymentModify(mchInfoConverter.toModel(dbRecord), mchStore, getReqParamJSON());
        } else {
            applymentResultByRPC = isvmchStoreApplymentService.firstStoreApplyment(mchInfoConverter.toModel(dbRecord), mchStore);
        }
        MchApplyment applymentResult = new MchApplyment();
        BeanUtils.copyProperties(applymentResultByRPC, applymentResult);
        applymentResult.setApplyId(recordId);
        // 状态不为失败时进行更新
        if (applymentResult.getState() != MchApplyment.STATE_REJECT_WAIT_MODIFY) {
            // db门店入驻信息
            String storeSuccResParameter = dbRecord.getStoreSuccResParameter();
            JSONArray jsonArray = new JSONArray();
            JSONArray arrayStore = getJSONArrayStore(jsonArray, storeSuccResParameter, storeId, applymentResult);

            applymentResult.setStoreSuccResParameter(arrayStore.toJSONString());
            // 不更新进件状态、渠道单号
            applymentResult.setState(null);
            applymentResult.setChannelApplyNo(null);
            // 更新数据
            mchApplymentService.updateById(applymentResult);
        }
        return ApiRes.ok();
    }

    /**
     * 河马付门店入驻查询
     **/
    @GetMapping("/storeApplyment/{recordId}")
    public ApiRes storeApplymentQuery(@PathVariable("recordId") String recordId) {

        MchApplyment dbRecord = mchApplymentService.getById(recordId);

        if (dbRecord == null || dbRecord.getState() != MchApplyment.STATE_SUCCESS) {
            throw new BizException("当前申请单状态不是成功，无法继续。");
        }

        // db入驻详情
        MchApplyment record = mchApplymentService.getById(recordId);

        IIsvmchStoreApplymentService isvmchStoreApplymentService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(record.getIfCode()) + "MchStoreApplymentService", IIsvmchStoreApplymentService.class);

        // 调起门店查询接口
        com.jeequan.jeepay.core.entity.MchApplyment applymentResultByRPC = isvmchStoreApplymentService.storeApplymentQuery(mchInfoConverter.toModel(dbRecord));

        if (applymentResultByRPC == null) {
            return ApiRes.ok();
        }

        try {
            MchApplyment applymentResult = new MchApplyment();
            applymentResult.setApplyId(recordId);
            applymentResult.setStoreSuccResParameter(applymentResultByRPC.getStoreSuccResParameter());
            if (StringUtils.isNotEmpty(applymentResultByRPC.getSuccResParameter())) {
                applymentResult.setSuccResParameter(applymentResultByRPC.getSuccResParameter());
            }
            // 更新数据
            mchApplymentService.updateById(applymentResult);
        } catch (Exception e) {
            logger.error("门店入驻更新数据库门店信息失败，申请单号{}", recordId);
        }

        return ApiRes.ok(applymentResultByRPC.getStoreSuccResParameter());
    }

    public static JSONArray getJSONArrayStore(JSONArray jsonArray, String storeSuccResParameter, String storeId, MchApplyment applymentResult) {
        if (StringUtils.isEmpty(storeSuccResParameter)) {
            JSONObject storeJson = new JSONObject();
            storeJson.put("storeId", storeId);
            storeJson.put("store_no", applymentResult.getChannelApplyNo());
            storeJson.put("state", applymentResult.getState());
            jsonArray.add(storeJson);
            applymentResult.setStoreSuccResParameter(jsonArray.toJSONString());
        } else {
            jsonArray = JSON.parseArray(storeSuccResParameter);
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject json = (JSONObject) jsonArray.get(i);
                if (storeId.equals(json.getString("storeId")) && applymentResult.getChannelApplyNo().equals(json.getString("store_no"))) {
                    jsonArray.remove(i);
                    break;
                }
            }
            JSONObject storeJson = new JSONObject();
            storeJson.put("storeId", storeId);
            storeJson.put("store_no", applymentResult.getChannelApplyNo());
            storeJson.put("state", applymentResult.getState());
            jsonArray.add(storeJson);
        }
        return jsonArray;
    }

    /**
     * 动态获取微信收付通  银行支行列表
     **/
    @GetMapping("/bankList/{mchNo}/{ifCode}/{isvNo}")
    public ApiRes bankList(@PathVariable("mchNo") String mchNo
            , @PathVariable("ifCode") String ifCode
            , @PathVariable("isvNo") String isvNo) {

        MchInfo mchInfo = mchInfoService.getById(mchNo);
        if (MchInfo.isNotIsv(mchInfo)) {
            throw new BizException("请选择特约商户类型");
        }

        String bankAliasCode = getValString("bankAliasCode");
        String cityCode = getValStringRequired("cityCode");
        String bankName = getValString("bankName");
        String branchName = getValString("branchName");

        IGetApplymentDataService getApplymentDataService = IsvFactory.getGetApplymentDataService(JeepayKit.getIfCodeOrigin(ifCode));
        try {
            // 调起接口
            List<JSONObject> list = getApplymentDataService.getBankBranchInfo(isvNo, bankAliasCode, cityCode, bankName, branchName);

            return ApiRes.ok(list);

        } catch (BizException e) {
            logger.info("请求异常", e);
            throw e;
        }
    }


    /**
     * 通用校验： 商户 / 商户类型 / 服务商  / 渠道商 / 接口开关 / 渠道商参数配置开关
     **/
    private void commonCheck(String applyId, String isvNo, String mchNo, String ifCode, boolean checkHasRecord) {

        MchInfo mchInfo = mchInfoService.getById(mchNo);

        if (!ObjUtil.isEmpty(applyId)) {
            MchApplyment existData = mchApplymentService.getById(applyId);
            if (existData.getState() != com.jeequan.jeepay.core.entity.MchApplyment.STATE_SAVE
                    && existData.getState() != com.jeequan.jeepay.core.entity.MchApplyment.STATE_REJECT_WAIT_MODIFY
                    && existData.getState() != com.jeequan.jeepay.core.entity.MchApplyment.STATE_WAIT_PRE_AUDIT_REJECT) {
                throw new BizException("当前商户状态不支持该操作");
            }
        }

        if (mchInfo == null || mchInfo.getState() != CS.YES) {
            throw new BizException("当前商户不可用");
        }

        if (!Objects.equals(mchInfo.getAgentNo(), getCurrentAgentNo())) {
            throw new BizException("该商户不是您名下的商户");
        }

        if (isvNo == null) {
            throw new BizException("请选择特约商户");
        }

        IsvInfoEntity isvInfoEntity = isvInfoService.getById(isvNo);
        if (isvInfoEntity == null || !isvInfoEntity.getState().equals(CS.YES)) {
            throw new BizException("当前渠道商不可用");
        }

        AgentInfo agentInfo = agentInfoService.getById(mchInfo.getAgentNo());
        if (agentInfo == null || !agentInfo.getState().equals(CS.YES)) {
            throw new BizException("当前服务商不可用");
        }

        PayInterfaceDefine payInterfaceDefine = payInterfaceDefineService.getById(ifCode);
        if (payInterfaceDefine == null || !payInterfaceDefine.getState().equals(CS.YES)) {
            throw new BizException("当前支付接口不可用");
        }
        if (payInterfaceDefine.getIsSupportApplyment() != CS.YES || payInterfaceDefine.getIsOpenApplyment() != CS.YES) {
            throw new BizException("当前支付接口不支持或未开启进件");
        }

        PayInterfaceConfig payInterfaceConfig = payInterfaceConfigService.getByInfoIdAndIfCode(CS.SYS_ROLE_TYPE.ISV, isvInfoEntity.getIsvNo(), ifCode);

        if (payInterfaceConfig == null || payInterfaceConfig.getState() != CS.YES) {
            throw new BizException("当前渠道商支付接口配置不可用");
        }

        if (checkHasRecord) {
            // 20220708 允许一个商户进件多次的情况
//            int count = mchApplymentService.count(MchApplyment.gw().eq(MchApplyment::getMchNo, mchNo).eq(MchApplyment::getIfCode, ifCode));
//            if(count > 0 ){
//                throw new BizException("该商户在当前通道已存在进件数据，不可再次发起");
//            }
        }
    }

    /**
     * @author: xiaoyu
     * @date: 2022/4/24 9:47
     * @describe: 河马付门店参数绑定
     */
    public void hmpaySubMchParamsModify(String configVal, String mchNo, String mchAppId) {
        try {

            MchApplyment tbMchApplyment = JSON.parseObject(configVal, MchApplyment.class);
            if (tbMchApplyment == null || StringUtils.isEmpty(tbMchApplyment.getChannelApplyNo())) {
                throw new BizException("参数为空！mchApplyment=" + tbMchApplyment);
            }
            if (StringUtils.isEmpty(tbMchApplyment.getStoreSuccResParameter())) {
                throw new BizException("门店信息为空！mchApplyment=" + tbMchApplyment);
            }

            HmpayIsvsubMchParams hmpayIsvsubMchParams = (HmpayIsvsubMchParams) configContextQueryService.queryIsvsubMchParams(mchNo, mchAppId, CS.IF_CODE.HMPAY);
            if (hmpayIsvsubMchParams == null) {
                hmpayIsvsubMchParams = new HmpayIsvsubMchParams();
            }
            PayInterfaceConfig updateRecord = new PayInterfaceConfig();
            // 门店信息
            hmpayIsvsubMchParams.setMchStoreConfig(tbMchApplyment.getStoreSuccResParameter());
            // 子商户号
            if (StringUtils.isEmpty(hmpayIsvsubMchParams.getSubAppId())) {
                hmpayIsvsubMchParams.setSubAppId(tbMchApplyment.getChannelApplyNo());
            }
            updateRecord.setIfParams(hmpayIsvsubMchParams.getJsonParams().toString());

            // 接口配置
            PayInterfaceConfig payInterfaceConfig = payInterfaceConfigService.getByInfoIdAndIfCode(CS.SYS_ROLE_TYPE.MCH_APP, mchAppId, tbMchApplyment.getIfCode());

            if (payInterfaceConfig != null) {
                updateRecord.setId(payInterfaceConfig.getId());
                payInterfaceConfigService.updateById(updateRecord);
            } else {

                updateRecord.setInfoType(CS.SYS_ROLE_TYPE.MCH_APP);
                updateRecord.setInfoId(mchAppId);
                updateRecord.setIfCode(tbMchApplyment.getIfCode());
                payInterfaceConfigService.save(updateRecord);

            }

        } catch (BizException e) {
            throw new BizException(e.getMessage());
        }
    }

    /**
     * 富友  电子协议生成
     **/
    @PostMapping("/elecContractGenerate/{recordId}")
    public ApiRes elecContractGenerate(@PathVariable("recordId") String recordId) {

        MchApplyment dbRecord = mchApplymentService.getById(recordId);
        if (dbRecord == null || (dbRecord.getState() != MchApplyment.STATE_WAIT_SIGN && dbRecord.getState() != MchApplyment.STATE_WAIT_VERIFY)) {
            throw new BizException("当前申请单状态错误，无法继续。");
        }

        IFuiouApplymentApiService fuiouApplymentApiService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(dbRecord.getIfCode()) + "ApplymentApiService", IFuiouApplymentApiService.class);

        try {
            // 调起接口
            com.jeequan.jeepay.core.entity.MchApplyment applymentResult = fuiouApplymentApiService.elecContractGenerate(mchInfoConverter.toModel(dbRecord));

            MchApplyment updateRecord = new MchApplyment();
            BeanUtils.copyProperties(applymentResult, updateRecord);

            // 更新数据
            updateRecord.setApplyId(recordId);
            mchApplymentService.updateById(updateRecord);

        } catch (BizException e) {
            logger.info("请求异常", e);
            throw e;
        }

        return ApiRes.ok(mchApplymentService.getById(recordId));
    }

    /**
     * 富友  电子协议签署
     **/
    @PostMapping("/elecContractSign/{recordId}")
    public ApiRes elecContractSign(@PathVariable("recordId") String recordId) {

        MchApplyment dbRecord = mchApplymentService.getById(recordId);
        if (dbRecord == null || dbRecord.getState() != MchApplyment.STATE_WAIT_SIGN) {
            throw new BizException("当前申请单状态不是待签约，无法继续。");
        }

        IFuiouApplymentApiService fuiouApplymentApiService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(dbRecord.getIfCode()) + "ApplymentApiService", IFuiouApplymentApiService.class);

        try {
            // 调起接口
            com.jeequan.jeepay.core.entity.MchApplyment applymentResult = fuiouApplymentApiService.elecContractSign(mchInfoConverter.toModel(dbRecord));

            MchApplyment updateRecord = new MchApplyment();
            BeanUtils.copyProperties(applymentResult, updateRecord);

            // 更新数据
            updateRecord.setApplyId(recordId);
            mchApplymentService.updateById(updateRecord);
        } catch (BizException e) {
            logger.info("请求异常", e);
            throw e;
        }

        return ApiRes.ok();
    }

    /**
     * 富友  上传图片
     **/
    @PostMapping("/fuiouUpload/{recordId}")
    public ApiRes fuiouUpload(@PathVariable("recordId") String recordId) {

        MchApplyment dbRecord = mchApplymentService.getById(recordId);
        if (dbRecord == null || (dbRecord.getState() != MchApplyment.STATE_AUDITING &&
                dbRecord.getState() != MchApplyment.STATE_WAIT_SIGN && dbRecord.getState() != MchApplyment.STATE_FINISH_SIGN)) {
            throw new BizException("当前申请单状态错误，无法继续。");
        }

        IFuiouApplymentApiService fuiouApplymentApiService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(dbRecord.getIfCode()) + "ApplymentApiService", IFuiouApplymentApiService.class);

        try {
            // 调起接口
            boolean result = fuiouApplymentApiService.uploadImg(mchInfoConverter.toModel(dbRecord));
            if (!result) {
                return ApiRes.customFail("图片上传失败");
            }

            // 上传成功，提交审核
            com.jeequan.jeepay.core.entity.MchApplyment applymentResult = fuiouApplymentApiService.attachConfirm(mchInfoConverter.toModel(dbRecord));

            MchApplyment updateRecord = new MchApplyment();
            BeanUtils.copyProperties(applymentResult, updateRecord);

            // 更新数据
            updateRecord.setApplyId(recordId);
            mchApplymentService.updateById(updateRecord);

        } catch (BizException e) {
            logger.info("请求异常", e);
            throw e;
        }

        return ApiRes.ok();
    }

    /**
     * 富友  提交审核
     **/
    @PostMapping("/fuiouConfirm/{recordId}")
    public ApiRes fuiouConfirm(@PathVariable("recordId") String recordId) {

        MchApplyment dbRecord = mchApplymentService.getById(recordId);
        if (dbRecord == null || (dbRecord.getState() != MchApplyment.STATE_AUDITING &&
                dbRecord.getState() != MchApplyment.STATE_WAIT_SIGN && dbRecord.getState() != MchApplyment.STATE_FINISH_SIGN)) {
            throw new BizException("当前申请单状态错误，无法继续。");
        }

        IFuiouApplymentApiService fuiouApplymentApiService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(dbRecord.getIfCode()) + "ApplymentApiService", IFuiouApplymentApiService.class);

        try {
            // 调起接口
            com.jeequan.jeepay.core.entity.MchApplyment applymentResult = fuiouApplymentApiService.attachConfirm(mchInfoConverter.toModel(dbRecord));

            MchApplyment updateRecord = new MchApplyment();
            mchInfoConverter.cp(applymentResult, updateRecord);

            // 更新数据
            updateRecord.setApplyId(recordId);
            mchApplymentService.updateById(updateRecord);

        } catch (BizException e) {
            logger.info("请求异常", e);
            throw e;
        }

        return ApiRes.ok();
    }

    /**
     * 富友  富友微信参数配置
     **/
    @PostMapping("/fuiouWxConfigSet/{recordId}")
    public ApiRes fuiouWxConfigSet(@PathVariable("recordId") String recordId) {

        String jsapiPath = getValString("configWxPayBaseUrl");
        String subAppid = getValString("configWxBindAppId");
        String subscribeAppid = getValString("configWxSubscribeAppId");

        MchApplyment dbRecord = mchApplymentService.getById(recordId);
        if (dbRecord == null || (dbRecord.getState() != MchApplyment.STATE_WAIT_SIGN && dbRecord.getState() != MchApplyment.STATE_AUDITING
                && dbRecord.getState() != MchApplyment.STATE_SUCCESS && dbRecord.getState() != MchApplyment.STATE_FINISH_SIGN)) {
            throw new BizException("当前申请单状态错误，无法继续。");
        }

        IFuiouApplymentApiService fuiouApplymentApiService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(dbRecord.getIfCode()) + "ApplymentApiService", IFuiouApplymentApiService.class);

        try {
            // 调起接口
            fuiouApplymentApiService.wechatConfigSet(mchInfoConverter.toModel(dbRecord), jsapiPath, subAppid, subscribeAppid);

        } catch (BizException e) {
            logger.info("请求异常", e);
            throw e;
        }

        return ApiRes.ok();
    }

    /**
     * 富友  获取微信参数配置
     **/
    @PostMapping("/fuiouWxConfigGet/{recordId}")
    public ApiRes fuiouWxConfigGet(@PathVariable("recordId") String recordId) {

        MchApplyment dbRecord = mchApplymentService.getById(recordId);
        if (dbRecord == null || (dbRecord.getState() != MchApplyment.STATE_WAIT_SIGN && dbRecord.getState() != MchApplyment.STATE_WAIT_VERIFY
                && dbRecord.getState() != MchApplyment.STATE_SUCCESS && dbRecord.getState() != MchApplyment.STATE_FINISH_SIGN)) {
            throw new BizException("当前申请单状态错误，无法继续。");
        }

        IFuiouApplymentApiService fuiouApplymentApiService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(dbRecord.getIfCode()) + "ApplymentApiService", IFuiouApplymentApiService.class);

        try {
            // 调起接口
            String wechatConfig = fuiouApplymentApiService.wechatConfigGet(mchInfoConverter.toModel(dbRecord));
            return ApiRes.ok(JSON.parseObject(wechatConfig));
        } catch (BizException e) {
            logger.info("请求异常", e);
            throw e;
        }

    }

    /**
     * 斗拱 分账配置
     **/
    @PostMapping("/dgpayConfigOpen/{recordId}")
    public ApiRes dgpayConfigOpen(@PathVariable("recordId") String recordId) {
        JSONObject paramJSON = getReqParamJSON();
        MchApplyment dbRecord = mchApplymentService.getById(recordId);
        if (dbRecord == null || (dbRecord.getState() != MchApplyment.STATE_WAIT_SIGN && dbRecord.getState() != MchApplyment.STATE_WAIT_VERIFY
                && dbRecord.getState() != MchApplyment.STATE_SUCCESS && dbRecord.getState() != MchApplyment.STATE_FINISH_SIGN)) {
            throw new BizException("当前申请单状态错误，无法继续。");
        }

        IDgApplymentApiService dgApplymentApiService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(dbRecord.getIfCode()) + "ApplymentApiService", IDgApplymentApiService.class);
        try {
            com.jeequan.jeepay.core.entity.MchApplyment mchApplyment = dgApplymentApiService.dgpayConfigOpen(mchInfoConverter.toModel(dbRecord), paramJSON);
            // 状态未改为待验证 则抛出错误信息
            if (StringUtils.isNotEmpty(mchApplyment.getApplyErrorInfo())) {
                return ApiRes.customFail(mchApplyment.getApplyErrorInfo());
            }
            // 更新数据
            MchApplyment updateRecord = new MchApplyment();
            updateRecord.setApplyId(recordId);
            updateRecord.setChannelVar1(mchApplyment.getChannelVar1());
            mchApplymentService.updateById(updateRecord);
            return ApiRes.ok();
        } catch (BizException e) {
            logger.info("请求异常", e);
            throw e;
        }

    }

    /**
     * 斗拱 分账配置查询
     **/
    @GetMapping("/dgpayConfigOpenQuery/{recordId}")
    public ApiRes dgpayConfigOpenQuery(@PathVariable("recordId") String recordId) {
        MchApplyment dbRecord = mchApplymentService.getById(recordId);
        if (dbRecord == null || (dbRecord.getState() != MchApplyment.STATE_WAIT_SIGN && dbRecord.getState() != MchApplyment.STATE_WAIT_VERIFY
                && dbRecord.getState() != MchApplyment.STATE_SUCCESS && dbRecord.getState() != MchApplyment.STATE_FINISH_SIGN)) {
            throw new BizException("当前申请单状态错误，无法继续。");
        }

        IDgApplymentApiService dgApplymentApiService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(dbRecord.getIfCode()) + "ApplymentApiService", IDgApplymentApiService.class);
        try {

            com.jeequan.jeepay.core.entity.MchApplyment mchApplyment = dgApplymentApiService.dgpayConfigOpenQuery(mchInfoConverter.toModel(dbRecord));
            // 状态未改为待验证 则抛出错误信息
            if (StringUtils.isNotEmpty(mchApplyment.getApplyErrorInfo())) {
                return ApiRes.customFail(mchApplyment.getApplyErrorInfo());
            }
            return ApiRes.ok(mchApplyment.getChannelVar2());
        } catch (BizException e) {
            logger.info("请求异常", e);
            throw e;
        }

    }

    /**
     * 斗拱 微信参数配置
     **/
    @PostMapping("/dgWxConfigSet/{recordId}")
    public ApiRes dgWxConfigSet(@PathVariable("recordId") String recordId) {

        String feeType = getValString("feeType");
        String jsapiPath = getValString("configWxPayBaseUrl");
        String configWxBindLiteAppId = getValString("configWxBindLiteAppId");
        String configWxBindAppId = getValString("configWxBindAppId");
        String bankChannelNo = getValString("bankChannelNo");
        String isvNo = getValStringRequired("isvNo");

        // 商户应用的 渠道配置页面  && 传输过的是ifCode
        String appConfigModeAndIfCode = getValString("appConfigModeAndIfCode");

        MchAppEntity mchAppEntity = mchAppService.getById(recordId);
        String mchNo = mchAppEntity.getMchNo();

        String ifCode = appConfigModeAndIfCode;

        IDgApplymentApiService dgApplymentApiService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(ifCode) + "ApplymentApiService", IDgApplymentApiService.class);

        try {
            // 调起接口
            com.jeequan.jeepay.core.entity.MchApplyment mchApplyment = dgApplymentApiService.wechatConfigSet(isvNo, mchNo, recordId, jsapiPath, feeType, configWxBindLiteAppId, configWxBindAppId, bankChannelNo, ifCode);
            if (mchApplyment.getState() == null || com.jeequan.jeepay.core.entity.MchApplyment.STATE_SUCCESS != mchApplyment.getState()) {
                return ApiRes.customFail(mchApplyment.getApplyErrorInfo());
            }
        } catch (BizException e) {
            logger.info("请求异常", e);
            throw e;
        }
        return ApiRes.ok();
    }

    /**
     * 斗拱 开通业务
     **/
    @PostMapping("/dgpayWxRealName/{recordId}")
    public ApiRes dgpayWxRealName(@PathVariable("recordId") String recordId) {
        JSONObject paramJSON = getReqParamJSON();
        MchApplyment dbRecord = mchApplymentService.getById(recordId);
        if (dbRecord == null || (dbRecord.getState() != MchApplyment.STATE_WAIT_SIGN && dbRecord.getState() != MchApplyment.STATE_WAIT_VERIFY
                && dbRecord.getState() != MchApplyment.STATE_SUCCESS && dbRecord.getState() != MchApplyment.STATE_FINISH_SIGN)) {
            throw new BizException("当前申请单状态错误，无法继续。");
        }

        IDgApplymentApiService dgApplymentApiService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(dbRecord.getIfCode()) + "ApplymentApiService", IDgApplymentApiService.class);

        try {
            dbRecord.setApplyDetailInfo(paramJSON.toString());

            com.jeequan.jeepay.core.entity.MchApplyment mchApplyment = dgApplymentApiService.wechatRealName(mchInfoConverter.toModel(dbRecord));
            // 状态未改为待验证 则抛出错误信息
            if (mchApplyment.getState() == null || com.jeequan.jeepay.core.entity.MchApplyment.STATE_SUCCESS != mchApplyment.getState()) {
                return ApiRes.customFail(mchApplyment.getApplyErrorInfo());
            }
            // 微信申请单号
            String applymentId = mchApplyment.getChannelApplyNo();
            paramJSON.put("applymentId", applymentId);
            // 更新数据
            MchApplyment updateRecord = new MchApplyment();
            updateRecord.setApplyDetailInfo(paramJSON.toString());
            updateRecord.setApplyId(recordId);
            mchApplymentService.updateById(updateRecord);
            return ApiRes.ok();
        } catch (BizException e) {
            logger.info("请求异常", e);
            throw e;
        }

    }

    /**
     * 乐刷 开通业务
     **/
    @PostMapping("/leshuapayConfigOpen/{recordId}")
    public ApiRes leshuapayConfigOpen(@PathVariable("recordId") String recordId) {
        JSONObject paramJSON = getReqParamJSON();
        MchApplyment dbRecord = mchApplymentService.getById(recordId);
        if (dbRecord == null || (dbRecord.getState() != MchApplyment.STATE_SUCCESS)) {
            throw new BizException("当前申请单状态错误，无法继续，只有进件成功，才能进行业务开通。");
        }
        ILeshuaApplymentApiService leshuaApplymentApiService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(dbRecord.getIfCode()) + "ApplymentApiService", ILeshuaApplymentApiService.class);
        try {
            dbRecord.setApplyDetailInfo(paramJSON.toString());
            com.jeequan.jeepay.core.entity.MchApplyment mchApplyment = leshuaApplymentApiService.leshuapayConfigOpen(mchInfoConverter.toModel(dbRecord));
            // 更新数据
            MchApplyment updateRecord = new MchApplyment();
            BeanUtils.copyProperties(mchApplyment, updateRecord);
            updateRecord.setApplyId(recordId);
            mchApplymentService.updateById(updateRecord);
            return ApiRes.ok();
        } catch (BizException e) {
            logger.info("请求异常", e);
            throw e;
        }
    }

    /**
     * 进件参数的配置
     **/
    @PostMapping("/lklAppConfig/{applyId}/{mchAppId}")
    public ApiRes configAppInfo(@PathVariable("applyId") String applyId, @PathVariable("mchAppId") String mchAppId) {
        JSONObject paramJSON = getReqParamJSON();
        // 拉卡拉商户号
        String merCupNo = paramJSON.getString("merCupNo");
        // 终端号
        String termNo = paramJSON.getString("termNo");
        // 微信子商户号
        String subMchId = paramJSON.getString("subMchId");

        MchApplyment tbMchApplyment = mchApplymentService.getById(applyId);
        if (tbMchApplyment == null || tbMchApplyment.getState() != MchApplyment.STATE_SUCCESS) {
            throw new BizException("进件不存在或状态不正确");
        }

        if (StringUtils.isEmpty(tbMchApplyment.getSuccResParameter())) {
            throw new BizException("不存在进件支付参数，请手动配置");
        }

        JSONObject paramsJson = new JSONObject();
        if (StringUtils.isNotEmpty(merCupNo)) {
            paramsJson.put("merCupNo", merCupNo);
        }
        if (StringUtils.isNotEmpty(subMchId)) {
            paramsJson.put("subMchId", subMchId);
        }
        if (StringUtils.isNotEmpty(termNo)) {
            paramsJson.put("termNo", termNo);
        }

        PayInterfaceConfig updateRecord = new PayInterfaceConfig();

        if (StringUtils.isNotEmpty(merCupNo) || StringUtils.isNotEmpty(subMchId) || StringUtils.isNotEmpty(termNo)) {
            updateRecord.setIfParams(paramsJson.toJSONString());
        } else {
            updateRecord.setIfParams(tbMchApplyment.getSuccResParameter());
        }

        PayInterfaceConfig payInterfaceConfig = payInterfaceConfigService.getByInfoIdAndIfCode(CS.SYS_ROLE_TYPE.MCH_APP, mchAppId, tbMchApplyment.getIfCode());

        if (payInterfaceConfig != null) {
            updateRecord.setId(payInterfaceConfig.getId());
            payInterfaceConfigService.updateById(updateRecord);
        } else {

            updateRecord.setInfoType(CS.SYS_ROLE_TYPE.MCH_APP);
            updateRecord.setInfoId(mchAppId);
            updateRecord.setIfCode(tbMchApplyment.getIfCode());
            payInterfaceConfigService.save(updateRecord);

        }

        return ApiRes.ok();
    }

    /**
     * 银联前置  新增支付类型
     **/
    @PostMapping("/payConf/{recordId}")
    public ApiRes payConfAdd(@PathVariable("recordId") String recordId) {

        JSONObject reqParamJSON = getReqParamJSON();

        MchApplyment dbRecord = mchApplymentService.getById(recordId);
        if (dbRecord == null || (dbRecord.getState() != MchApplyment.STATE_AUDITING && dbRecord.getState() != MchApplyment.STATE_REJECT_WAIT_MODIFY
                && dbRecord.getState() != MchApplyment.STATE_SUCCESS)) {
            throw new BizException("当前申请单状态错误，无法继续。");
        }

        IUtmpayApplymentApiService applymentApiService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(dbRecord.getIfCode()) + "ApplymentApiService", IUtmpayApplymentApiService.class);

        String channelApplyNo = dbRecord.getChannelApplyNo();

        // 调起接口
        ChannelRetMsg channelRetMsg = applymentApiService.mchPayConfAdd(reqParamJSON, dbRecord.getIsvNo(), dbRecord.getMchNo(), channelApplyNo);

        if (channelRetMsg.getChannelState() == ChannelRetMsg.ChannelState.CONFIRM_SUCCESS) {
            return ApiRes.ok(channelRetMsg.getChannelOrderId());
        } else {
            return ApiRes.customFail(channelRetMsg.getChannelErrMsg());
        }

    }

    /**
     * 银联前置  查询第三方交易识别码
     **/
    @PostMapping("/mchPartner/{recordId}/{mchAppId}")
    public ApiRes getMchPartner(@PathVariable("recordId") String recordId, @PathVariable("mchAppId") String mchAppId) {

        MchApplyment dbRecord = mchApplymentService.getById(recordId);
        if (dbRecord == null || dbRecord.getState() != MchApplyment.STATE_SUCCESS) {
            throw new BizException("当前申请单状态错误，无法继续。");
        }

        IUtmpayApplymentApiService applymentApiService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(dbRecord.getIfCode()) + "ApplymentApiService", IUtmpayApplymentApiService.class);

        // String apiCode = getValStringRequired("apiCode");

        // 调起接口
        ChannelRetMsg channelRetMsg = applymentApiService.getMchPartner(UtmpayConfig.WX_API_CODE, dbRecord.getIsvNo(), dbRecord.getMchNo(), mchAppId);

        if (channelRetMsg.getChannelState() == ChannelRetMsg.ChannelState.CONFIRM_SUCCESS) {
            return ApiRes.ok(JSON.parseObject(channelRetMsg.getChannelOrderId()));
        } else {
            return ApiRes.customFail(channelRetMsg.getChannelErrMsg());
        }

    }

    /**
     * 获取银行编码
     **/
    @GetMapping("/bankCode/{ifCode}")
    public ApiRes getBankCode(@PathVariable("ifCode") String ifCode) {

        JSONObject queryParams = getReqParamJSON();

        IApplymentResourceService applymentResourceService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(ifCode) + "ApplymentResourceService", IApplymentResourceService.class);

        IPage<JSONObject> page = applymentResourceService.getBankCode(getIPage(), queryParams);

        return ApiRes.page(page);
    }

    /**
     * 进件类 继承自IApplymentResourceService
     * type 自定义业务种类 获取商户号和json数据对象进行特定操作
     * 现用于：国通星驿付安心签签署
     **/
    @PostMapping("iApplyRes/sendPubRequst/{ifCode}")
    public ApiRes sendPubRequst(@PathVariable("ifCode") String ifCode) {
        // 获取业务类型，用于前端调一个接口可执行不同的逻辑 不必传
        String type = getValString("operationType");
        // 获取当前商户信息
        String mchNo = getValStringRequired("mchNo");
        String applyId = getValString("applyId");
        String jsonStr = getValStringRequired("jsonStr");
        IApplymentResourceService applymentResourceService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(ifCode) + "ApplymentResourceService", IApplymentResourceService.class);
        return ApiRes.ok(applymentResourceService.sendPubRequst(type, mchNo, applyId, jsonStr));
    }

    /**
     * 进件api
     **/
    @PostMapping("/applymentNextBiz/{applyId}")
    public ApiRes applymentNextBiz(@PathVariable("applyId") String applyId) {
        String method = getValStringRequired("method");
        JSONObject paramJSON = getReqParamJSON();

        try {
            MchApplyment tbMchApplyment = mchApplymentService.getById(applyId);

            IApplymentApiService applymentApiService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(tbMchApplyment.getIfCode()) + "ApplymentApiService", IApplymentApiService.class);
            com.jeequan.jeepay.core.entity.MchApplyment applymentResultByRPC = applymentApiService.entry(method, mchInfoConverter.toModel(tbMchApplyment), paramJSON);

            // 更新数据
            MchApplyment applymentResult = new MchApplyment();
            BeanUtils.copyProperties(applymentResultByRPC, applymentResult);
            applymentResult.setApplyId(applyId);
            mchApplymentService.updateById(applymentResult);

            return ApiRes.ok(applymentResult);
        } catch (Exception e) {
            throw new BizException(e.getMessage());
        }
    }

    /**
     * 获取渠道商渠道配置参数
     **/
    @GetMapping("/getIsvChannelConfig/{mchNo}/{ifCode}/{isvNo}")
    public ApiRes applyPregetIsvChannelConfigCheck(@PathVariable("mchNo") String mchNo
            , @PathVariable("ifCode") String ifCode, @PathVariable("isvNo") String isvNo) {

        // 已过校验，跳过校验步骤

        // 渠道商信息
        IsvInfoEntity isvInfoEntity = isvInfoService.getById(isvNo);
        // 渠道配置
        PayInterfaceConfig payInterfaceConfig = payInterfaceConfigService.getByInfoIdAndIfCode(CS.SYS_ROLE_TYPE.ISV, isvInfoEntity.getIsvNo(), ifCode);
        // 返回渠道配置参数
        IsvChannelConfig channelConfig = JSON.parseObject(payInterfaceConfig.getIfParams(), IsvChannelConfig.class);

        return ApiRes.ok(channelConfig);
    }

    /**
     * 进件数据变更
     */
    @PreAuthorize("hasAuthority('ENT_MCH_APPLYMENT_ADD')")
    @PostMapping("/modifyApplyment")
    public ApiRes modifyApplyment() {

        String operationType = getValString("operationType");
        MchModifyApplymentModel reqModel = getObject(MchModifyApplymentModel.class);
        Assert.notNull(reqModel.getMchApplyId(), "缺少商户编号[mchApplyId]");
        Assert.notNull(reqModel.getModifyApplyType(), "缺少变更类型[modifyApplyType]");

        if (!"1".equals(operationType) && !"2".equals(operationType)) {
            throw new BizException("非法的操作类型[operationType]");
        }

        MchApplyment mchApplyment = mchApplymentService.getById(reqModel.getMchApplyId());
        Assert.notNull(mchApplyment, "未获取到商户信息");

        switch (reqModel.getModifyApplyType()) {
            case MchModifyApplyment.MODIFY_TYPE_BASE:
                Assert.isTrue(!CharSequenceUtil.isEmpty(reqModel.getMchShortName()), "商户简称[mchShortName]不能为空");
                break;
            case MchModifyApplyment.MODIFY_TYPE_SETTLEMENT:
                Assert.notNull(reqModel.getSettAccountType(), "结算账户类型[settleAccountType]不能为空");
                Assert.notNull(reqModel.getIllegal(), "结算类型[illegal]不能为空");
                Assert.notNull(reqModel.getSettAccountNo(), "结算账户号[settAccountNo]不能为空");

                if ("Y".equals(reqModel.getIllegal())) {
                    Assert.notNull(reqModel.getSettAccountName(), "结算账户名称[settAccountName]不能为空");
                    Assert.notNull(reqModel.getSettAccountIdcardNo(), "结算人身份证号[settAccountIdcardNo]不能为空");
                    Assert.notNull(reqModel.getSettAccountIdcard1Img(), "结算人身份证卡号面图片[settAccountIdcard1Img]不能为空");
                    Assert.notNull(reqModel.getSettAccountIdcard2Img(), "结算人身份证国徽面图片[settAccountIdcard2Img]不能为空");
                    Assert.notNull(reqModel.getSettAccountIdcardEffectBegin(), "结算人身份证有效期开始时间[settAccountIdcardEffectBegin]不能为空");
                    Assert.notNull(reqModel.getSettAccountIdcardEffectEnd(), "结算人身份证有效期截止时间[settAccountIdcardEffectEnd]不能为空");
                }
                // 其他的校验放到业务代码中处理
                break;
            case MchModifyApplyment.MODIFY_TYPE_SETTLEMENT_TYPE:
                // 变更结算类型
                Assert.notNull(reqModel.getSettlementType(), "结算方式[settlementType]不能为空");
                if (!reqModel.getSettlementType().equals(CS.SETTLEMENT_TYPE.D1)
                        && !reqModel.getSettlementType().equals(CS.SETTLEMENT_TYPE.D0)
                        && !reqModel.getSettlementType().equals(CS.SETTLEMENT_TYPE.T1)) {
                    throw new BizException("结算方式[settlementType]必须为【D0】、【D1】、【T1】");
                }
                break;
            default:
                throw new BizException("未知的变更类型");
        }

        // check 只做存储，具体操作交由商户端进行
        MchModifyApplyment modifyApplyment = new MchModifyApplyment();

        JeeUserDetails currentUser = getCurrentUser();
        modifyApplyment.setCreatedUid(currentUser.getSysUserId());
        modifyApplyment.setCreatedBy(currentUser.getUsername());
        modifyApplyment.setModifyApplyType(reqModel.getModifyApplyType());
        modifyApplyment.setApplyDetailInfo(JSON.toJSONString(reqModel));
        modifyApplyment.setModifyApplyId(SeqKit.genMchNotifyApplyNo());
        modifyApplyment.setApplyId(reqModel.getMchApplyId());
        modifyApplyment.setApplyPageType(CS.SYS_ROLE_TYPE.AGENT + "_" + getCurrentUser().getLoginType());

        modifyApplyment.setState(com.jeequan.jeepay.core.entity.MchApplyment.STATE_AFFIRM);
        modifyApplyment.setChannelMchNo(mchApplyment.getChannelMchNo());
        modifyApplyment.setMchNo(mchApplyment.getMchNo());
        modifyApplyment.setOtherOperationType(operationType);
        if ("1".equals(operationType)){
            modifyApplyment.setRemark("本地系统变更");
        }
        modifyApplymentService.save(modifyApplyment);

        return ApiRes.ok();
    }

    /**
     * 进件数据变更中的数据回显
     */
    @PreAuthorize("hasAuthority('ENT_MCH_APPLYMENT_LIST')")
    @GetMapping("/modifyApplyment")
    public ApiRes getModifyApplyment() {
        // 变更类型，1: 本地变更； 2: 变更并同步到上游通道
        MchModifyApplymentModel reqModel = getObject(MchModifyApplymentModel.class);
        String modifyApplyId = reqModel.getModifyApplyId();
        LambdaQueryWrapper<MchModifyApplymentEntity> qWrapper = Wrappers.lambdaQuery();
        if (StringUtils.isNotEmpty(modifyApplyId)) {
            qWrapper.eq(MchModifyApplymentEntity::getModifyApplyId, modifyApplyId);
        } else {
            Assert.notNull(reqModel.getMchApplyId(), "缺少商户编号[mchApplyId]");
            Assert.notNull(reqModel.getModifyApplyType(), "缺少商户编号[modifyApplyType]");
            qWrapper.eq(MchModifyApplymentEntity::getModifyApplyType, reqModel.getModifyApplyType());
            qWrapper.eq(MchModifyApplymentEntity::getApplyId, reqModel.getMchApplyId());
            qWrapper.eq(MchModifyApplymentEntity::getState, com.jeequan.jeepay.core.entity.MchApplyment.STATE_AUDITING);
        }
        MchModifyApplymentEntity existData = modifyApplymentService.getOne(qWrapper);
        return ApiRes.ok(existData);
    }

    @GetMapping("/getModifyApplyments")
    public ApiRes getModifyApplyments() {
        MchModifyApplymentEntity searchRecord = getObject(MchModifyApplymentEntity.class);
        // 扩展员仅查询自己的数据
        if (getCurrentUser().isEpUser()) {
            searchRecord.setEpUserId(getCurrentUser().getSysUser().getSysUserId());
        }
        // 时间搜索
        Date[] searchDateRange = searchRecord.buildQueryDateRange();
        if (searchDateRange[0] != null) {
            searchRecord.setFirstDate(searchDateRange[0]);
        }
        if (searchDateRange[1] != null) {
            searchRecord.setLastDate(searchDateRange[1]);
        }
        Page<MchModifyApplymentEntity> page = getIPage(false);
        Page<MchModifyApplymentEntity> result = mchApplymentService.getModifyApplyments(page, searchRecord);
        //整理json数据
        result.getRecords().forEach(item -> {
            if (!item.getApplyDetailInfo().isEmpty()) {
                try {
                    MchModifyApplymentModel mchModifyApplymentModel = JSONObject.parseObject(item.getApplyDetailInfo(), new TypeReference<MchModifyApplymentModel>() {
                    }.getType());
                    item.setModifyModel(mchModifyApplymentModel);
                } catch (Exception e) {
                    throw new BizException("解析json变更数据出错！");
                }

            }
        });

        return ApiRes.page(result);
    }
    /**
     * 获取进件成功的通道
     * @return
     */
    @GetMapping("/getSucceedIfName")
    public ApiRes getSucceedIfName() {
        // 可查看自己和全部下级代理数据
        String currentAgentNo = getCurrentAgentNo();
        List<String> subAgentNoList = agentInfoService.queryAllSubAgentNo(currentAgentNo);
        List<MchApplyment> applymentList = mchApplymentService.list(MchApplyment.gw().select(MchApplyment::getIfCode, MchApplyment::getIfName)
                .eq(MchApplyment::getState, MchApplyment.STATE_SUCCESS)
                .in(MchApplyment::getAgentNo,subAgentNoList)
                .groupBy(MchApplyment::getIfCode));
        return ApiRes.ok(applymentList);
    }

    /**
     * 获取进件成功的渠道
     * @return
     */
    @GetMapping("/getSucceedIsvName")
    public ApiRes getSucceedIsvName() {
        MchApplyment mchApplyment = getObject(MchApplyment.class);
        // 可查看自己和全部下级代理数据
        String currentAgentNo = getCurrentAgentNo();
        List<String> subAgentNoList = agentInfoService.queryAllSubAgentNo(currentAgentNo);
        // 自己和下级服务商
        if (CollUtil.isNotEmpty(subAgentNoList)){
            mchApplyment.setSubAgentNoList(subAgentNoList);
        }
        List<MchApplyment> succeedIsvName = mchApplymentService.getSucceedIsvName(mchApplyment);
        return ApiRes.ok(succeedIsvName);
    }
}



