package com.malk.lianan.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.malk.lianan.utils.AesUtil;
import com.malk.lianan.utils.RsaUtil;
import com.malk.lianan.service.LianAnGyPayService;
import com.malk.server.aliwork.YDConf;
import com.malk.server.aliwork.YDParam;
import com.malk.server.common.McR;
import com.malk.service.aliwork.YDClient;
import com.malk.utils.UtilDateTime;
import com.malk.utils.UtilMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
@Slf4j
public class LianAnGyServiceImpl implements LianAnGyPayService {
    // 测试环境数据
    private final static String GYPAY_API_URL="http://sk-uat.tech.dccnet.com.cn:8343/api/dtxg"; // 财资云服务的地址
    private final static String GYPAY_API_SYS_ID="NBLASY"; // 接入系统编号
    private final static String GYPAY_API_SYS_NAME="宁波联安商业"; // 接入系统名称
    private final static String GYPAY_API_TENANT_ID="TN100123"; // 商户号
    private final static String GYPAY_API_TENANT_NAME="org_01"; // 付款单位名称
    private final static String GYPAY_API_ACCOUNT_NO="123456"; // 付款单位账号
    private final static String GYPAY_API_TYPE_NO="YW21081817205273002001"; // 业务类型编号
    private final static String GYPAY_API_TYPE_NAME="bt_sett"; // 业务类型名称

    private final static String GYPAY_API_PUB_KEY="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCns/4GnEfTQtKhOBxZz57F8IZvKalhvX7iOZz2M7amfsO4jsiPNNbgHqKjX4hzyIeAmCmFqLDZMDIM2a4y/oNC/ikZl2yHcYexRT/xTgbR+EM2dDQqfUjDGDD3XsXRbmVbSvvKg8OhLwd4jRTHOGooetg8IP4SC66dPreJlNBVywIDAQAB";
    private final static String GYPAY_API_PRI_KEY="MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKez/gacR9NC0qE4HFnPnsXwhm8pqWG9fuI5nPYztqZ+w7iOyI801uAeoqNfiHPIh4CYKYWosNkwMgzZrjL+g0L+KRmXbIdxh7FFP/FOBtH4QzZ0NCp9SMMYMPdexdFuZVtK+8qDw6EvB3iNFMc4aih62Dwg/hILrp0+t4mU0FXLAgMBAAECgYBcRYmgY36Ve6/eqrvWoojOig+9vCOJNrVIjcCSKlP1+cuAkXdCbCVKPTDpSRgP9Kaxl4dJFk7vwTfYoDDbt/PKFX277V6bdkjMwNclwniilSU+QMEpmu71HeaXBAiRm5TLEflhcxV2Wy5D0VyBLnPWodH1rGjtfiO6V9SbQf8bGQJBANF5RJ+Ie/+dgAYm/L4Mb3f+Pb/yipUuHcqSZlfd/eMJDtEcp7xcvNFRivbl6IcXvncvL1uInkGdriOe3nmqti0CQQDM86LS8PsseuaVdpt7HCKivub0mI/wcvZ8mUVZZ4jFibPNsSKl1+QreGk/e2QrkyOySC5e2lf5HOEGC/lREm7XAkAL5K/BwxUPQVkIgGQvQjN+A6Br6pB1weWNH9zRtlf48QW3V8IqTrWlyNR0Cj+2k+GLkNFGiC48GYDOovGMxOWNAkEAqCDNV4H8ana/pajQz2M7PoqgZ9Kncba9YWVSsI7wciwOZhSDucyrDsYOgNc2S1C/Hcd80q8HMAJyzkUQV2NprQJACwsH8IEEE/kwSesQlb8fa+ugr+tNnFVPj1xqM4kPD5Dj3XP7B8KWUwL4a4/Y1S6BtoqCL4CAfuEHTw7MlUA2NA==";
    private final static String GYPAY_API_AES_KEY="d2a1b3173e494c38";

    private final static String GYPAY_API_SIGN_PUB_KEY="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCmudhlkVXrFP1DB0r11LvVpy8nYVO9sR2tYLXCkQxXE4HR2VlihCO43B2v/Ep3tlny4l/OX++AQX4sJpO8vAnCRmNIAgXKXAfvre1HTSkJf9vb8G9sf4UsZX2bLEOtH4wOO7Osv8Za98WzBHBRrqESI91Z4GSE0/8ucMp6V7EZ5wIDAQAB";

    private final static String KEY_RSA = "RSA";
    private final static String KEY_RSA_SIGNATURE = "SHA256WithRSA";
    private static BouncyCastleProvider bouncyCastleProvider = new BouncyCastleProvider();

    private static final String SHA256WithRSA = "SHA256WithRSA";
    private static final String X509 = "X.509";

    private final static String[] purpose = new String[]{"工资","奖金","报销","补贴","社保","货款","佣金","租金","稿费","公积金","养老金","助学金","劳务费","演出费","福利费","代返还","企业年金","保险理赔","保费退还","付保险款","副食补贴","纳税退还","基金撤销","基金赎回","基金分红","员工安家费","校内奖学金","国家助学金","励志奖学金","保险到期还款","个人贷款转存","期货交易保证金","继承或赠与款项","证券交易结算资金","个人小件商品付款","债券投资本金和收益","信托投资本金和收益","期货投资本金和收益","其他投资本金和收益","农、副、矿产品收购款","个人债权或产权转让收益","服务费","养老保险","失业保险","工伤保险","医保代发","运输费","工会费","外服工资","集团内付款","遗属生活费","风沙费","调节金","培训费","独生子女费","押金","咨询费","慰问金","劳模津贴","体检费","补助","报刊费","电话费","交通费"};

    @Autowired
    private YDClient ydClient;

    @Override
    public McR pay(Map map) {
        String formInstId = UtilMap.getString(map, "formInstId");

        Map item = new HashMap();

        Map formData = ydClient.queryData(YDParam.builder()
                .formInstanceId(formInstId)
                .build(), YDConf.FORM_QUERY.retrieve_id).getFormData();

        String fkgs = UtilMap.getString(formData, "textField_mjzgymw0");//付款公司
        String fkfyhzh = UtilMap.getString(formData, "textField_mjzgymw1");//付款方银行账号

        int retryNUM = UtilMap.getInt(formData, "numberField_mkp4wc2r");//重试次数

        if (retryNUM > 0){
            item.put("BillsPayOrderNo",formInstId + "_" + retryNUM);//外部系统单据编号
        }else {
            item.put("BillsPayOrderNo",formInstId);//外部系统单据编号
        }

        //时间戳转化为yyyy-MM-dd
        long fkrq = UtilMap.getLong(formData, "dateField_mkdsowjd");
        String fkrqStr = DateUtil.format(new Date(fkrq), "yyyy-MM-dd");
        item.put("PaymentDate",fkrqStr);//付款日期(期望支付日期)
        item.put("BusinessTypeCode",GYPAY_API_TYPE_NO);//业务类型编号
        item.put("BusinessTypeName",GYPAY_API_TYPE_NAME);//业务类型名称
        item.put("PayOrgName",fkgs);//付款单位名称
        item.put("PayAccountNo",fkfyhzh);//付款方银行账号
        String payChannel = UtilMap.getString(formData, "selectField_mjm87v3v");
        String payChannelValue = "";
        //支付方式 1.直联支付 2.线下支付 3.全额支付 4.差额支付
        switch (payChannel){
            case "直联支付":payChannelValue = "1";break;
            case "线下支付":payChannelValue = "2";break;
            default:break;
        }
        item.put("PayChannel",payChannelValue);
        item.put("SumPayAmount",UtilMap.getDouble(formData, "numberField_mkdsowjo").toString());//合计付款金额
        item.put("PayCurrencyType","CNY");//币种(为空,默认: CNY 有付款账号时，不能为 空)

        item.put("PayCurrencyName","人民币");//币种名称(为空,默认:人民币, 有付款账号时，不能为空)
        String whetherUrgent = UtilMap.getString(formData, "radioField_mkdsowje");
        item.put("WhetherUrgent","是".equals(whetherUrgent) ? 1 : 2);//是否加急 1.是 2.否
        String note = UtilMap.getString(formData, "textareaField_mkdsowjj");//备注
        item.put("Note",note);//备注

        List<Map> paymentRecList = new ArrayList<>();

        List<Map> details = UtilMap.getList(formData, "tableField_mjsl53ki");
        for (Map detail : details) {
            String billsPayOrderNo = UtilMap.getString(detail,"textField_mk129s2t");//收款方单据编号
            String privateAmount = UtilMap.getDouble(detail,"numberField_mjsl53ke").toString();//付款金额
            String receiveAccountNo = UtilMap.getString(detail,"textField_mjsl53kd");//收款方银行账号
            String receiveAccountName = UtilMap.getString(detail,"textField_mjsl53kb");//收款方账户名称
            String payUse = UtilMap.getString(detail,"textareaField_mjsl53kh");//费用明细

            Map paymentRec = new HashMap();
            paymentRec.put("BillsPayOrderNo",billsPayOrderNo);
            paymentRec.put("PrivateAmount",privateAmount);
            paymentRec.put("ReceiveAccountNo",receiveAccountNo);
            paymentRec.put("ReceiveAccountName",receiveAccountName);
            paymentRec.put("PayUse","付款");//摘要长度上限20
            paymentRec.put("Purpose","付款");

            paymentRecList.add(paymentRec);
        }

        item.put("PaymentRecList",paymentRecList);

        Map<String,Object> data = UtilMap.map("ParamSet", Arrays.asList(item));

        String requestNo = gyPost("T0022", data);

        ydClient.operateData(YDParam.builder()
                .formInstanceId(formInstId)
                .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("textField_mmolqml1",requestNo)))
                .build(), YDConf.FORM_OPERATION.update);

        return McR.success();
    }

    @Override
    public McR retryPay(Map map) {
        String formInstId = UtilMap.getString(map, "formInstId");

        Map formData = ydClient.queryData(YDParam.builder()
                .formInstanceId(formInstId)
                .build(), YDConf.FORM_QUERY.retrieve_id).getFormData();

        String fkdwmc = UtilMap.getString(formData, "textField_mjzgymw0");//付款单位名称
        String fkfyhzh = UtilMap.getString(formData, "textField_mjqroqxb");//付款方银行账号

        String skdwmc = UtilMap.getString(formData, "textField_mjzgprn9");//收款单位名称
        String skfyhzh = UtilMap.getString(formData, "textField_mjqpry6t");//收款方银行账号

        //时间戳转化为yyyy-MM-dd
        long fkrq = UtilMap.getLong(formData, "dateField_mkdsowjd");
        String fkrqStr = DateUtil.format(new Date(fkrq), "yyyy-MM-dd");

        //支付方式 1.直联支付 2.线下支付 3.全额支付 4.差额支付
        String payChannel = UtilMap.getString(formData, "selectField_mjm87v3v");
        String payChannelValue = "";
        switch (payChannel){
            case "直联支付":payChannelValue = "1";break;
            case "线下支付":payChannelValue = "2";break;
            default:break;
        }

        String whetherUrgent = UtilMap.getString(formData, "radioField_mkdsowje");//是否加急 1.是 2.否(为空,默认: 2)
        String whetherUrgentValue = "";
        switch (whetherUrgent){
            case "是":whetherUrgentValue = "1";break;
            case "否":whetherUrgentValue = "2";break;
            default:break;
        }

        String payAmount = UtilMap.getDouble(formData, "numberField_mjqt1xrt").toString();

        String fymx = UtilMap.getString(formData, "textareaField_mjsl53kh");//费用明细

        String purpose = UtilMap.getString(formData, "selectField_mjzgprmw");//付款类型 用途

        int retryNum = UtilMap.getInt(formData, "numberField_mkf5q51o");//重试次数

        Map item = new HashMap();
        item.put("BillsPayOrderNo",formInstId+"_"+retryNum);//外部系统单据编号
        item.put("PaymentDate",fkrqStr);//付款日期(期望支付日期)
        item.put("PayType","1");//付款类型 默认1.单笔付款，表示一对一（对公/对私）支付
        item.put("BusinessTypeCode",GYPAY_API_TYPE_NO);//业务类型编号
        item.put("BusinessTypeName",GYPAY_API_TYPE_NAME);//业务类型名称
        item.put("PayOrgName",fkdwmc);//付款单位名称
        item.put("PayAccountNo",fkfyhzh);//付款方银行账号
        item.put("PayChannel",payChannelValue);//支付方式 1.直联支付 2.线下支付 3.全额支付 4.差额支付
        item.put("PayAmount",payAmount);//付款金额
        item.put("PayCurrencyType","CNY");//币种(为空,默认: CNY 有付款账号时，不能为 空)
        item.put("PayCurrencyName","人民币");//币种名称(为空,默认:人民币, 有付款账号时，不能为空)
        item.put("WhetherUrgent",whetherUrgentValue);//是否加急 1.是 2.否
        item.put("Remark",fymx);//附言
        item.put("PayUse",purpose);//摘要长度上限20
        item.put("Purpose",purpose);

        Map paymentRec = new HashMap();
        paymentRec.put("ReceiveAccountNo",skfyhzh);
        paymentRec.put("ReceiveAccountName",skdwmc);
        paymentRec.put("ReceiveCurrencyCode","CNY");
        paymentRec.put("ReceiveCurrencyName","人民币");
        item.put("PaymentRec",paymentRec);

        Map<String,Object> data = UtilMap.map("ParamSet", Arrays.asList(item));

        //工银-单笔付款
        String requestNo = gyPost("T0002", data);

        //回写请求号
        ydClient.operateData(YDParam.builder()
                .formInstanceId(formInstId)
                .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("textField_mmolqml1",requestNo)))
                .build(), YDConf.FORM_OPERATION.update);


        return McR.success();
    }

    @Async
    @Override
    public void callback(Map result) {
        String resultCode = UtilMap.getString(result, "ResultCode");
        String resultMsg = UtilMap.getString(result, "ResultMsg");
        Map resultInfo = ((List<Map>) UtilMap.getList(result, "ResultSet")).get(0);
        String[] split = UtilMap.getString(resultInfo, "BillsPayOrderNo").split("_");
        boolean isRetry = false;
        if (split.length > 1) {
            isRetry = true;
        }
        String billsPayOrderNo = split[0];//外部系统单据编号  格式：实例id/实例id_重试次数

        if ("0000".equals(resultCode)) {
            //付款单生成成功 财资云支付结果
            String payStatus = UtilMap.getString(resultInfo, "PayStatus");//业务状态：1-支付中，2-支付成功，3-支付失败，4- 已退款，5-部分支付成功，6-部分退款，10-未知
            String payStatusName = getPayStatusName(payStatus);//业务状态名称
            String relPaymentDate = UtilMap.getString(resultInfo, "RelPaymentDate");//实际付款日期(部分付款有成功时为最大支付日期)
            String failReasons = UtilMap.getString(resultInfo, "FailReasons");

            String relBillsCode = UtilMap.getString(resultInfo, "RelBillsCode");//工银实际单据号

            //更新付款单信息
            ydClient.operateData(YDParam.builder()
                    .formInstanceId(billsPayOrderNo)
                    .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mkp4wc2q, textareaField_mjs6mcgf, textField_mkp5mn5l","生成成功","",relBillsCode)))
                    .build(), YDConf.FORM_OPERATION.update);

            log.info("ResultMsg：{}，PayStatusName：{}，实际付款日期：{}",resultMsg, payStatusName,relPaymentDate);

            List<Map> batchList = (List<Map>) UtilMap.getList(resultInfo, "BatchList");

            if (batchList != null && !batchList.isEmpty()) {
                //有付款明细
                for (Map map : batchList) {
                    String billsPayOrderNo2 = UtilMap.getString(map, "BillsPayOrderNo");
                    String payStatus2 = UtilMap.getString(map, "PayStatus");
                    String PayStatusName2 = getPayStatusName(payStatus2);
                    String relPaymentDate2 = UtilMap.getString(map, "RelPaymentDate");
                    String failReasons2 = UtilMap.getString(resultInfo, "FailReasons");

                    //查询付款明细
                    List<Map> data = (List<Map>) ydClient.queryData(YDParam.builder()
                            .searchCondition(JSONObject.toJSONString(UtilMap.map("textField_mjs6mcfn, textField_mk128ce5", billsPayOrderNo, billsPayOrderNo2)))
                            .formUuid("FORM-2D646B4D1C1F4628A0DEA1072656901143Y9").build(), YDConf.FORM_QUERY.retrieve_list).getData();

                    //付款明细逐条更新 防止集成自动化并发
                    for (Map datum : data) {
                        String detailFormInstId = UtilMap.getString(datum, "formInstanceId");

                        ydClient.operateData(YDParam.builder()
                                .formInstanceId(detailFormInstId)
                                .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mjs6mcgg, dateField_mkdm7y7c, textareaField_mjs6mcgf",PayStatusName2, Strings.isNotBlank(relPaymentDate2) ? DateUtil.parse(relPaymentDate2, "yyyy-MM-dd").getTime() : null,failReasons2)))
                                .build(), YDConf.FORM_OPERATION.update);

                        try {
                            Thread.sleep(3000);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            }else {
                //无付款明细
                if (isRetry){
                    //重试付款
                    ydClient.operateData(YDParam.builder()
                            .formInstanceId(billsPayOrderNo)
                            .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mjs6mcgg, dateField_mkdm7y7c, textareaField_mjs6mcgf",payStatusName,DateUtil.parse(relPaymentDate, "yyyy-MM-dd").getTime(),failReasons)))
                            .build(), YDConf.FORM_OPERATION.update);
                }else {
                    //首次付款
                    ydClient.operateData(YDParam.builder()
                            .searchCondition(JSONObject.toJSONString(UtilMap.map("textField_mjs6mcfn", billsPayOrderNo)))
                            .formUuid("FORM-2D646B4D1C1F4628A0DEA1072656901143Y9")
                            .formDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mjs6mcgg, dateField_mkdm7y7c, textareaField_mjs6mcgf",payStatusName,DateUtil.parse(relPaymentDate, "yyyy-MM-dd").getTime(),failReasons)))
                            .build(), YDConf.FORM_OPERATION.upsert);
                }
            }
        }else {
            //付款单生成失败
            String failReasons = UtilMap.getString(resultInfo, "FailReasons");
            log.info("ResultMsg：{}，FailReasons：{}",resultMsg, failReasons);

            ydClient.operateData(YDParam.builder()
                    .formInstanceId(billsPayOrderNo)
                    .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mkp4wc2q, textareaField_mjs6mcgf","生成失败",failReasons)))
                    .build(), YDConf.FORM_OPERATION.update);

        }
    }

    @Override
    public McR salaryPay(Map map) {
        String formInstId = UtilMap.getString(map, "formInstId");

        Map item = new HashMap();

        Map formData = ydClient.queryData(YDParam.builder()
                .formInstanceId(formInstId)
                .build(), YDConf.FORM_QUERY.retrieve_id).getFormData();

        String fkgs = UtilMap.getString(formData, "textField_mjzgymw0");//付款公司
        String fkfyhzh = UtilMap.getString(formData, "textField_mjzgymw1");//付款方银行账号

        int retryNUM = UtilMap.getInt(formData, "numberField_mkp4wc2r");//重试次数

        if (retryNUM > 0){
            item.put("BillsPayOrderNo",formInstId + "_" + retryNUM);//外部系统单据编号
        }else {
            item.put("BillsPayOrderNo",formInstId);//外部系统单据编号
        }

        item.put("PayType","2");//外部系统单据编号

        //时间戳转化为yyyy-MM-dd
        long fkrq = UtilMap.getLong(formData, "dateField_mkdsowjd");
        String fkrqStr = DateUtil.format(new Date(fkrq), "yyyy-MM-dd");
        item.put("PaymentDate",fkrqStr);//付款日期(期望支付日期)
        item.put("BusinessTypeCode",GYPAY_API_TYPE_NO);//业务类型编号
        item.put("BusinessTypeName",GYPAY_API_TYPE_NAME);//业务类型名称
        item.put("PayOrgName",fkgs);//付款单位名称
        item.put("PayAccountNo",fkfyhzh);//付款方银行账号
        String payChannel = UtilMap.getString(formData, "selectField_mjm87v3v");
        String payChannelValue = "";
        //支付方式 1.直联支付 2.线下支付 3.全额支付 4.差额支付
        switch (payChannel){
            case "直联支付":payChannelValue = "1";break;
            case "线下支付":payChannelValue = "2";break;
            default:break;
        }
        item.put("PayChannel",payChannelValue);
        item.put("PayAmount",UtilMap.getDouble(formData, "numberField_mjmc84h7").toString());//合计付款金额
        item.put("PayCurrencyType","CNY");//币种(为空,默认: CNY 有付款账号时，不能为 空)

        item.put("PayCurrencyName","人民币");//币种名称(为空,默认:人民币, 有付款账号时，不能为空)
        String whetherUrgent = UtilMap.getString(formData, "radioField_mkdsowje");
        item.put("WhetherUrgent","是".equals(whetherUrgent) ? 1 : 2);//是否加急 1.是 2.否
        String note = UtilMap.getString(formData, "textareaField_mkdsowjj");//备注
        item.put("Remark",note);//备注
        String payUse = UtilMap.getString(formData, "textareaField_mjmc84h9");//费用明细
        item.put("PayUse","工资");//摘要长度上限20
        item.put("Purpose","工资");

        List<Map> batchPrivateRecList = new ArrayList<>();

        List<Map> details = UtilMap.getList(formData, "tableField_mjqqlln3");
        for (Map detail : details) {
            String billsPayOrderNo = UtilMap.getString(detail,"textField_mkns6lx6");//收款方单据编号
            String privateAmount = UtilMap.getDouble(detail,"numberField_mjqt1xrt").toString();//付款金额
            String receiveAccountNo = UtilMap.getString(detail,"textField_mjqpry6r");//收款方银行账号
            String receiveAccountName = UtilMap.getString(detail,"textField_mjqpry6s");//收款方账户名称
            String receiveBranchCode = UtilMap.getString(detail,"textField_mkdeg10p");//收款方开户行行号（收款方开户行行号、行名至少填写一项）
            String receiveBranchName = UtilMap.getString(detail,"textField_mjqpry6u");//收款方开户行行号（收款方开户行行号、行名至少填写一项）

            Map paymentRec = new HashMap();
            paymentRec.put("BillsPayOrderNo",billsPayOrderNo);
            paymentRec.put("PrivateAmount",privateAmount);
            paymentRec.put("ReceiveAccountNo",receiveAccountNo);
            paymentRec.put("ReceiveAccountName",receiveAccountName);
            paymentRec.put("ReceiveBranchCode",receiveBranchCode);
            paymentRec.put("ReceiveBranchName",receiveBranchName);



            batchPrivateRecList.add(paymentRec);
        }

        item.put("BatchPrivateRecList",batchPrivateRecList);

        Map<String,Object> data = UtilMap.map("ParamSet", Arrays.asList(item));

        String requestNo = gyPost("T0003", data);

        //回写请求号
        ydClient.operateData(YDParam.builder()
                .formInstanceId(formInstId)
                .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("textField_mmolqml1",requestNo)))
                .build(), YDConf.FORM_OPERATION.update);


        return McR.success();
    }

    @Override
    public McR reimburse(Map map) {
        String formInstId = UtilMap.getString(map, "formInstId");

        Map item = new HashMap();

        Map formData = ydClient.queryData(YDParam.builder()
                .formInstanceId(formInstId)
                .build(), YDConf.FORM_QUERY.retrieve_id).getFormData();

        String fkgs = UtilMap.getString(formData, "textField_mjzgymw0");//付款公司
        String fkfyhzh = UtilMap.getString(formData, "textField_mjzgymw1");//付款方银行账号

        int retryNUM = UtilMap.getInt(formData, "numberField_mkp4wc2r");//重试次数

        if (retryNUM > 0){
            item.put("BillsPayOrderNo",formInstId + "_" + retryNUM);//外部系统单据编号
        }else {
            item.put("BillsPayOrderNo",formInstId);//外部系统单据编号
        }

        //时间戳转化为yyyy-MM-dd
        long fkrq = UtilMap.getLong(formData, "dateField_mkdsowjd");
        String fkrqStr = DateUtil.format(new Date(fkrq), "yyyy-MM-dd");
        item.put("PaymentDate",fkrqStr);//付款日期(期望支付日期)
        item.put("BusinessTypeCode",GYPAY_API_TYPE_NO);//业务类型编号
        item.put("BusinessTypeName",GYPAY_API_TYPE_NAME);//业务类型名称
        item.put("PayOrgName",fkgs);//付款单位名称
        item.put("PayAccountNo",fkfyhzh);//付款方银行账号
        String payChannel = UtilMap.getString(formData, "selectField_mjm87v3v");
        String payChannelValue = "";
        //支付方式 1.直联支付 2.线下支付 3.全额支付 4.差额支付
        switch (payChannel){
            case "直联支付":payChannelValue = "1";break;
            case "线下支付":payChannelValue = "2";break;
            default:break;
        }
        item.put("PayChannel",payChannelValue);
        item.put("SumPayAmount",UtilMap.getDouble(formData, "numberField_mkdsowjo").toString());//合计付款金额
        item.put("PayCurrencyType","CNY");//币种(为空,默认: CNY 有付款账号时，不能为 空)

        item.put("PayCurrencyName","人民币");//币种名称(为空,默认:人民币, 有付款账号时，不能为空)
        String whetherUrgent = UtilMap.getString(formData, "radioField_mkdsowje");
        item.put("WhetherUrgent","是".equals(whetherUrgent) ? 1 : 2);//是否加急 1.是 2.否
        String note = UtilMap.getString(formData, "textareaField_mkdsowjj");//备注
        item.put("Note",note);//备注

        List<Map> paymentRecList = new ArrayList<>();

        List<Map> details = UtilMap.getList(formData, "tableField_mjm9e1zc");
        for (Map detail : details) {
            String billsPayOrderNo = UtilMap.getString(detail,"textField_mk1278lu");//收款方单据编号
            String privateAmount = UtilMap.getDouble(detail,"numberField_mjm9e1zl").toString();//付款金额
            String receiveAccountNo = UtilMap.getString(detail,"textField_mjm9e1zf");//收款方银行账号
            String receiveAccountName = UtilMap.getString(detail,"textField_mjm9e1zg");//收款方账户名称
            String payUse = UtilMap.getString(detail,"textareaField_mjsl53kh");//费用明细

            Map paymentRec = new HashMap();
            paymentRec.put("BillsPayOrderNo",billsPayOrderNo);
            paymentRec.put("PrivateAmount",privateAmount);
            paymentRec.put("ReceiveAccountNo",receiveAccountNo);
            paymentRec.put("ReceiveAccountName",receiveAccountName);
            paymentRec.put("PayUse","报销");//摘要长度上限20
            paymentRec.put("Purpose","报销");

            paymentRecList.add(paymentRec);
        }

        item.put("PaymentRecList",paymentRecList);

        Map<String,Object> data = UtilMap.map("ParamSet", Arrays.asList(item));

        String requestNo = gyPost("T0022", data);

        //回写请求号
        ydClient.operateData(YDParam.builder()
                .formInstanceId(formInstId)
                .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("textField_mmolqml1",requestNo)))
                .build(), YDConf.FORM_OPERATION.update);


        return McR.success();
    }

    private String gyPost(String MesgNo,Map<String,Object> data){
        log.info("data：{}",data);

        Map<String,Object> head = new HashMap<>();
        head.put("MesgNo",MesgNo);
        head.put("TenantId",GYPAY_API_TENANT_ID);
        head.put("Timestamp", UtilDateTime.getLocalDateTimeTimeStamp());
        head.put("SystemNo",GYPAY_API_SYS_ID);
        head.put("SystemName",GYPAY_API_SYS_NAME);
        String requestNo = IdUtil.nanoId(6);
        head.put("RequestNo", requestNo);

        Map<String,Object> body = new HashMap<>();
        String encrypt = AesUtil.encrypt(JSON.toJSONString(data),GYPAY_API_AES_KEY);
        body.put("Data", encrypt);
        String signed= RsaUtil.sign(JSONObject.toJSONString(data).getBytes(),GYPAY_API_PRI_KEY);
        body.put("Sign", signed);

        Map<String,Object> Cmscloud = new HashMap<>();
        Cmscloud.put("Head",head);
        Cmscloud.put("Body",body);
        String indata=JSONObject.toJSONString(UtilMap.map("Cmscloud",Cmscloud));

        System.out.println(indata);

        String result= HttpUtil.createPost(GYPAY_API_URL).body(indata).execute().body();

        System.out.println(result);

        JSONObject resultjson=JSONObject.parseObject(result);
        JSONObject resultBody = resultjson.getJSONObject("Cmscloud").getJSONObject("Body");

        String resultData=AesUtil.decrypt(resultBody.getString("Data"),GYPAY_API_AES_KEY);
        System.out.println(resultData);

//        Map resultMap = (Map) JSONObject.parse(resultData);

        return requestNo;
    }

    private String getPayStatusName(String payStatus){
        //业务状态：1-支付中，2-支付成功，3-支付失败，4- 已退款，5-部分支付成功，6-部分退款，10-未知
        String payStatusName = "";
        switch (payStatus){
            case "1": payStatusName = "支付中"; break;
            case "2": payStatusName = "支付成功"; break;
            case "3": payStatusName = "支付失败"; break;
            case "4": payStatusName = "已退款"; break;
            case "5": payStatusName = "部分支付成功"; break;
            case "6": payStatusName = "部分退款"; break;
            case "10": payStatusName = "未知"; break;
            default: payStatusName = "未知"; break;
        }

        return payStatusName;
    }
}
