package com.malk.huagao.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.malk.huagao.service.EqbService;
import com.malk.huagao.utils.HTTPHelper;
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.service.dingtalk.DDClient;
import com.malk.utils.UtilHttp;
import com.malk.utils.UtilMap;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class EqbServiceImpl implements EqbService {
    @Autowired
    private YDConf ydConf;

    @Autowired
    private YDClient ydClient;

    @Autowired
    private DDClient ddClient;

    // 应用ID
    final static String appId = "5112033166";
    // 应用密钥（AppSecret）
    final static String appKey = "c0641a1f648a68a7014be5a490f0159a";
    // e签宝接口调用域名（正式环境）
    final static String host = "https://openapi.esign.cn";

    //正式环境模板id 经销商模板
    final static String jxs_templateId = "6a23f76742d74b858cdc2259a5d5c32f";
    //正式环境模板id 其他客户模板
    final static String qtkh_templateId = "8b7fef2257bc4093ada330dbf7c874c5";
    //正式环境模板id 采购订单模板
    final static String cgdd_templateId = "a0827f8946994ebfbed7f44e6b8a6ed8";

    @Value(value = "${eqb.downloadFilePath}")
    private String downloadFilePath;

    @Value(value = "${server.host}")
    private String serverHost;

    @Value(value = "${eqb.signatoryPsnId}")
    private String signatoryPsnId;

    @Value(value = "${dingtalk.atUserId}")
    private String atUserId;



    @Async
    @Override
    public void autoAgree(String signFlowId,String processInstanceId) {
        MDC.put("MDC_KEY_PID","1003");

        //1、签署后文件回写宜搭
        Map fileInfo = downloadSignedFile(signFlowId);
        String fileId = UtilMap.getString(fileInfo, "fileId");
        String fileName = UtilMap.getString(fileInfo, "fileName");

        String downloadUrl = serverHost + "/huagao/eqb/files/" + fileId + ".pdf?option=download";
        String previewUrl = serverHost + "/huagao/eqb/files/" + fileId + ".pdf?option=preview";

        //更新宜搭实例签署后文件
        Map formData = new HashMap();
        Map file = new HashMap();
        file.put("downloadUrl",downloadUrl);
        file.put("name",fileName);
        file.put("previewUrl",previewUrl);
        file.put("url",downloadUrl);
        file.put("ext","pdf");

        formData.put("attachmentField_mj8dt3g2",Arrays.asList(file));

        ydClient.operateData(YDParam.builder()
                .updateFormDataJson(JSONObject.toJSONString(formData))
                .formInstanceId(processInstanceId)
                .build(), YDConf.FORM_OPERATION.update);

        //2、自动同意宜搭审批节点
        String activityId = "node_ockpz6phx73";//审批节点id【e签宝签署（系统节点，禁止删除！）】
        long taskId = 0;
        String userId = "";//审批人id

        //获取审批记录
        List<Map> result = (List<Map>) ydClient.queryData(YDParam.builder()
                .processInstanceId(processInstanceId)
                .build(), YDConf.FORM_QUERY.retrieve_approval_record).getResult();
        for (Map approveInfo : result) {
            if (activityId.equals(UtilMap.getString(approveInfo, "activityId"))){
                //获取taskId
                taskId = UtilMap.getLong(approveInfo, "taskId");
                userId = UtilMap.getString(approveInfo, "operatorUserId");
                break;
            }
        }

        //审批
        Map body = new HashMap();
        body.put("outResult","AGREE");//AGREE：同意 DISAGREE：拒绝。
        body.put("appType",ydConf.getAppType());
        body.put("systemToken",ydConf.getSystemToken());
        body.put("remark","e签宝签署完成，自动通过");//审批意见
        body.put("processInstanceId",processInstanceId);//审批实例id
        body.put("userId",userId);//用户userid
        body.put("taskId",taskId);//任务id

        UtilHttp.doPost("https://api.dingtalk.com/v1.0/yida/tasks/execute", ddClient.initTokenHeader(), null,body);
    }

    @Async
    @Override
    public McR sign(Map map) {
        MDC.put("MDC_KEY_PID","1003");
        //1、查询宜搭实例详情
        String formInstId = UtilMap.getString(map, "formInstId");

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

        String type = UtilMap.getString(formData, "selectField_mj89qndi");//用印文件类型

        String fileName = UtilMap.getString(formData, "textField_meqr38kq");//用印文件名称

        String signType = UtilMap.getString(formData, "radioField_mk0s5sf9");//签章类型

        JSONObject reqBodyObj = new JSONObject();

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


        switch (type){
            case "销售合同-经销商":
                getJxsObj(formData, components, reqBodyObj, fileName);
                break;
            case "销售合同-其他客户":
                getQtkhObj(formData,components,reqBodyObj,fileName);
                break;
            case "采购订单":
                getCgddObj(formData,components,reqBodyObj,fileName);
                break;
            default:break;
        }

        //2、填充模板生成文件
        Map result = eqbPost("/v3/files/create-by-doc-template", reqBodyObj);

        String fileId = UtilMap.getString(result,"fileId");

        //文档转换pdf需时间
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        //3、基于文件发起签署
        JSONObject reqBodyObj2 = new JSONObject();
        //设置待签署文件信息
        Map docs = new HashMap();
        docs.put("fileId", fileId);
        reqBodyObj2.put("docs", Arrays.asList(docs));

        //签署流程配置项
        Map signFlowConfig = new HashMap();
        signFlowConfig.put("signFlowTitle",fileName);
        signFlowConfig.put("autoFinish",true);
        signFlowConfig.put("notifyUrl",serverHost + "/huagao/eqb/callback");//回调地址
        reqBodyObj2.put("signFlowConfig",signFlowConfig);

        //签署方信息
        //我方
        Map signer = new HashMap();
        signer.put("signerType",1);//签署方类型，0 - 个人，1 - 企业/机构，2 - 法定代表人，3 - 经办人

        Map orgSignerInfo = new HashMap();
        orgSignerInfo.put("orgId","a5ec8fb7d8cc4276bd486824df0ec640");//华高机构id
        //企业/机构经办人信息
        Map transactorInfo = new HashMap();
        transactorInfo.put("psnId",signatoryPsnId);//陈伟东
        orgSignerInfo.put("transactorInfo",transactorInfo);
        signer.put("orgSignerInfo",orgSignerInfo);

        /*Map psnSignerInfo = new HashMap();
        psnSignerInfo.put("psnId",signatoryPsnId);//陈伟东
        signer.put("psnSignerInfo",psnSignerInfo);*/

        Map signField = new HashMap();
        signField.put("fileId",fileId);
        signField.put("customBizNum",formInstId);
        Map normalSignFieldConfig = new HashMap();
        normalSignFieldConfig.put("freeMode",true);
            /*normalSignFieldConfig.put("autoSign",true);
            normalSignFieldConfig.put("signFieldStyle",1);
            Map signFieldPosition = new HashMap();
            signFieldPosition.put("positionPage",1);
            normalSignFieldConfig.put("signFieldPosition",signFieldPosition);*/
        signField.put("normalSignFieldConfig",normalSignFieldConfig);
        signer.put("signFields",Arrays.asList(signField));

        reqBodyObj2.put("signers",Arrays.asList(signer));

        //他方
        String jbr = "";
        String jbrdh = "";
        String orgName = "";
        if ("双方签章".equals(signType)){
            switch (type){
                case "销售合同-经销商":
                    jbr = UtilMap.getString(formData, "textField_mk0s5sfa");//需方经办人
                    jbrdh = UtilMap.getString(formData, "textField_mf50cbqw");//需方经办人电话
                    orgName = UtilMap.getString(formData, "textField_mjaukh2p");//需方名称
                    break;
                case "销售合同-其他客户":
                    jbr = UtilMap.getString(formData, "textField_mk0s5sfh");//需方经办人
                    jbrdh = UtilMap.getString(formData, "textField_mk0s5sfg");//需方经办人电话
                    orgName = UtilMap.getString(formData, "textField_mjaukh2p");//需方名称
                    break;
                case "采购订单":
                    jbr = UtilMap.getString(formData, "textField_mj8dt3g8");//供方经办人
                    jbrdh = UtilMap.getString(formData, "textField_mj8dt3g9");//供方经办人电话
                    orgName = UtilMap.getString(formData, "textField_mj8dt3g7");//供方名称
                    break;
                default:break;
            }

            Map signer2 = new HashMap();
            signer2.put("signerType",1);//签署方类型，0 - 个人，1 - 企业/机构，2 - 法定代表人，3 - 经办人

            Map orgSignerInfo2 = new HashMap();
            orgSignerInfo2.put("orgName",orgName);//对方机构名称
            //企业/机构经办人信息
            Map transactorInfo2 = new HashMap();
            transactorInfo2.put("psnAccount",jbrdh);//经办人账号标识，手机号或邮箱，必须配合psnName（经办人姓名）传入
            Map psnInfo = new HashMap();
            psnInfo.put("psnName",jbr);//经办人姓名
            transactorInfo2.put("psnInfo",psnInfo);
            orgSignerInfo2.put("transactorInfo",transactorInfo2);
            signer2.put("orgSignerInfo",orgSignerInfo2);

            Map signField2 = new HashMap();
            signField2.put("fileId",fileId);
            signField2.put("customBizNum",formInstId);
            Map normalSignFieldConfig2 = new HashMap();
            normalSignFieldConfig2.put("freeMode",true);

            signField2.put("normalSignFieldConfig",normalSignFieldConfig2);
            signer2.put("signFields",Arrays.asList(signField2));

            reqBodyObj2.put("signers",Arrays.asList(signer,signer2));
        }

        Map result2 = eqbPost("/v3/sign-flow/create-by-file", reqBodyObj2);

        String signFlowId = UtilMap.getString(result2, "signFlowId");


        //4、回写签署地址
        JSONObject reqBodyObj3 = new JSONObject();
        Map operator = new HashMap();
        operator.put("psnId", signatoryPsnId);
        reqBodyObj3.put("operator", operator);
        Map result3 = eqbPost("/v3/sign-flow/" + signFlowId + "/sign-url", reqBodyObj3);

        String shortUrl = UtilMap.getString(result3, "shortUrl");

        ydClient.operateData(YDParam.builder()
                .formInstanceId(formInstId)
                .content("签署地址："+shortUrl)
                .userId("yida_pub_account")
                .atUserId(atUserId)//陈伟东
                .build(), YDConf.FORM_OPERATION.remarks);

        if ("双方签章".equals(signType)){
            System.out.println("获取对方签署地址");
            JSONObject reqBodyObj4 = new JSONObject();
            Map operator2 = new HashMap();
            operator2.put("psnAccount", jbrdh);
            reqBodyObj4.put("operator", operator2);
            reqBodyObj4.put("needLogin", true);
            Map result4 = eqbPost("/v3/sign-flow/" + signFlowId + "/sign-url", reqBodyObj4);

            String shortUrl2 = UtilMap.getString(result4, "shortUrl");

            ydClient.operateData(YDParam.builder()
                    .formInstanceId(formInstId)
                    .content("对方签署地址："+shortUrl2)
                    .userId("yida_pub_account")
                    .build(), YDConf.FORM_OPERATION.remarks);
        }


        return McR.success();
    }

    private void getJxsObj(Map formData,List<Map> components,JSONObject reqBodyObj,String fileName){
        String dgdbh = UtilMap.getString(formData, "textField_mjas1rkm");//订购单编号
        String xf = UtilMap.getString(formData, "textField_mjaukh2p");//需方
        String xfdz = UtilMap.getString(formData, "textareaField_mf50cbqt");//需方地址
        String xfdh = UtilMap.getString(formData, "textField_mf50cbqw");//需方电话
        String xfjbr = UtilMap.getString(formData, "textField_mj8dt3fj");//需方经办人
        String gfdh = UtilMap.getString(formData, "textField_mjau7ffr");//供方电话
        String gfjbr = UtilMap.getString(formData, "textField_mjauqjr9");//供方经办人
        long ddrq = UtilMap.getLong(formData, "dateField_mj8dt3fa");//订单日期
        String ghkjxybh = UtilMap.getString(formData, "textField_mjas1rkn");//供货框架协议编号
        Double jehj = UtilMap.getDouble(formData, "numberField_me1335n7");//金额合计
        String jehjdx = UtilMap.getString(formData, "textField_mf50cbvj");//金额合计大写
        String fktj = UtilMap.getString(formData, "radioField_mf50cbu7");//付款条件
        String xfnsrsbh = UtilMap.getString(formData, "textField_mf50cbuj");//需方纳税人识别号
        String xfkhyh = UtilMap.getString(formData, "textField_mf50cbup");//需方开户银行
        String xfzh = UtilMap.getString(formData, "textField_mf50cbuk");//需方账号

        List<Map> xshtmxList = UtilMap.getList(formData, "tableField_mf50cbre");//销售合同明细
        List<Map> jhdzList = UtilMap.getList(formData, "tableField_mj8dt3fk");//交货地址

        //订购单编号
        Map jxsComponent = new HashMap();
        jxsComponent.put("componentKey", "dgdbh");
        jxsComponent.put("componentValue", dgdbh);

        //需方
        Map jxsComponent2 = new HashMap();
        jxsComponent2.put("componentKey", "xf");
        jxsComponent2.put("componentValue", xf);

        //需方地址
        Map jxsComponent3 = new HashMap();
        jxsComponent3.put("componentKey", "xfdz");
        jxsComponent3.put("componentValue", xfdz);

        //需方电话
        Map jxsComponent4 = new HashMap();
        jxsComponent4.put("componentKey", "xfdh");
        jxsComponent4.put("componentValue", xfdh);

        //需方经办人
        Map jxsComponent5 = new HashMap();
        jxsComponent5.put("componentKey", "xfjbr");
        jxsComponent5.put("componentValue", xfjbr);

        //供方电话
        Map jxsComponent6 = new HashMap();
        jxsComponent6.put("componentKey", "gfdh");
        jxsComponent6.put("componentValue", gfdh);

        //供方经办人
        Map jxsComponent7 = new HashMap();
        jxsComponent7.put("componentKey", "gfjbr");
        jxsComponent7.put("componentValue", gfjbr);

        //订单日期
        Map jxsComponent8 = new HashMap();
        jxsComponent8.put("componentKey", "ddrq");
        jxsComponent8.put("componentValue", ddrq);

        //供货框架协议编号
        Map jxsComponent9 = new HashMap();
        jxsComponent9.put("componentKey", "ghkjxybh");
        jxsComponent9.put("componentValue", ghkjxybh);

        //金额合计
        Map jxsComponent10 = new HashMap();
        jxsComponent10.put("componentKey", "jehj");
        jxsComponent10.put("componentValue", jehj);

        //金额合计大写
        Map jxsComponent11 = new HashMap();
        jxsComponent11.put("componentKey", "jehjdx");
        jxsComponent11.put("componentValue", jehjdx);

        //付款条件
        Map jxsComponent12 = new HashMap();
        if ("款到发货".equals(fktj)){
            jxsComponent12.put("componentKey", "xkhh");
            jxsComponent12.put("componentValue", true);
        }else {
            jxsComponent12.put("componentKey", "qt");
            jxsComponent12.put("componentValue", true);
        }

        //需方纳税人识别号
        Map jxsComponent13 = new HashMap();
        jxsComponent13.put("componentKey", "xfnsrsbh");
        jxsComponent13.put("componentValue", xfnsrsbh);

        //需方开户银行
        Map jxsComponent14 = new HashMap();
        jxsComponent14.put("componentKey", "xfkhyh");
        jxsComponent14.put("componentValue", xfkhyh);

        //需方账号
        Map jxsComponent15 = new HashMap();
        jxsComponent15.put("componentKey", "xfzh");
        jxsComponent15.put("componentValue", xfzh);

        //销售合同明细
        List<Map> xshtmx = new ArrayList<>();
        xshtmx.add(getRowMap(false));
        for (int i = 0; i < xshtmxList.size(); i++) {
            String cpmc = UtilMap.getString(xshtmxList.get(i), "textField_mf50cbrf");//产品名称
            String cpxh = UtilMap.getString(xshtmxList.get(i), "textField_mf50cbrg");//产品型号
            String dw = UtilMap.getString(xshtmxList.get(i), "textField_mf50cbrh");//单位
            String xssl = UtilMap.getString(xshtmxList.get(i), "numberField_mfbx1pr4");//销售数量
            double lsdj = UtilMap.getDouble(xshtmxList.get(i), "numberField_mf50cbri");//零售单价
            double pfyhdj = UtilMap.getDouble(xshtmxList.get(i), "numberField_mf50cbrj");//批发优惠单价
            int zbq = UtilMap.getInt(xshtmxList.get(i), "numberField_mjb71qay");//质保期
            String zbqValue = zbq > 0 ? zbq + "年" : "";
            if (i == 0){
                xshtmx.add(getRowMap(false,i+1,cpmc,cpxh,dw,lsdj,pfyhdj,zbqValue));
            }else {
                xshtmx.add(getRowMap(true,i+1,cpmc,cpxh,dw,lsdj,pfyhdj,zbqValue));
            }
        }
        Map jxsComponent16 = new HashMap();
        jxsComponent16.put("componentKey", "xshtmx");
        jxsComponent16.put("componentValue", JSONObject.toJSONString(xshtmx));

        //交货地址
        List<Map> jhdz = new ArrayList<>();
        jhdz.add(getRowMap(false));
        for (int i = 0; i < jhdzList.size(); i++) {
            String shdz = UtilMap.getString(jhdzList.get(i), "textField_mj8dt3fl");//收货地址
            String shr = UtilMap.getString(jhdzList.get(i), "textField_mj8dt3fm");//收货人
            String shrlxdh = UtilMap.getString(jhdzList.get(i), "textField_mj8dt3fn");//收货人联系电话

            if (i == 0){
                jhdz.add(getRowMap(false,i+1,shdz,shr,shrlxdh));
            }else {
                jhdz.add(getRowMap(true,i+1,shdz,shr,shrlxdh));
            }
        }
        Map jxsComponent17 = new HashMap();
        jxsComponent17.put("componentKey", "jhdz");
        jxsComponent17.put("componentValue", JSONObject.toJSONString(jhdz));

        Map jxsComponent19 = new HashMap();
        jxsComponent19.put("componentKey", "xf2");
        jxsComponent19.put("componentValue", xf);

        Map jxsComponent20 = new HashMap();
        jxsComponent20.put("componentKey", "xfdz2");
        jxsComponent20.put("componentValue", xfdz);

        components.add(jxsComponent);
        components.add(jxsComponent2);
        components.add(jxsComponent3);
        components.add(jxsComponent4);
        components.add(jxsComponent5);
        components.add(jxsComponent6);
        components.add(jxsComponent7);
        components.add(jxsComponent8);
        components.add(jxsComponent9);
        components.add(jxsComponent10);
        components.add(jxsComponent11);
        components.add(jxsComponent12);
        components.add(jxsComponent13);
        components.add(jxsComponent14);
        components.add(jxsComponent15);
        components.add(jxsComponent16);
        components.add(jxsComponent17);
        components.add(jxsComponent19);
        components.add(jxsComponent20);

        if (!"款到发货".equals(fktj)){
            Map jxsComponent18 = new HashMap();
            jxsComponent18.put("componentKey", "qtnr");
            jxsComponent18.put("componentValue", fktj);
            components.add(jxsComponent18);
        }

        // 构建请求Body体
        reqBodyObj.put("docTemplateId", jxs_templateId);
        reqBodyObj.put("fileName", fileName+".pdf");
        reqBodyObj.put("components", components);
    }

    private void getQtkhObj(Map formData, List<Map> components, JSONObject reqBodyObj, String fileName){
        String htbh = UtilMap.getString(formData, "textField_mjb71q95");//合同编号
        String jf = UtilMap.getString(formData, "textField_mjaukh2p");//甲方
        double xsze = UtilMap.getDouble(formData, "numberField_mjb71qac");//销售总额
        String fkfs = UtilMap.getString(formData, "textField_mjb886fw");//付款方式
        String jfnsrsbh = UtilMap.getString(formData, "textField_mjb71q9w");//甲方纳税人识别号
        String jfdb = UtilMap.getString(formData, "textField_mjb886fx");//甲方代表
        String yfdb = UtilMap.getString(formData, "textField_mj8dt3fj");//乙方代表

        List<Map> xshtmxList = UtilMap.getList(formData, "tableField_mjb71qab");//销售合同明细

        //订购单编号
        Map jxsComponent = new HashMap();
        jxsComponent.put("componentKey", "htbh");
        jxsComponent.put("componentValue", htbh);

        //甲方
        Map jxsComponent2 = new HashMap();
        jxsComponent2.put("componentKey", "jf");
        jxsComponent2.put("componentValue", jf);

        //销售总额
        Map jxsComponent3 = new HashMap();
        jxsComponent3.put("componentKey", "xsze");
        jxsComponent3.put("componentValue", xsze);

        //付款方式
        Map jxsComponent4 = new HashMap();
        jxsComponent4.put("componentKey", "fkfs");
        jxsComponent4.put("componentValue", fkfs);

        //甲方纳税人识别号
        Map jxsComponent5 = new HashMap();
        jxsComponent5.put("componentKey", "jfnsrsbh");
        jxsComponent5.put("componentValue", jfnsrsbh);

        //甲方代表
        Map jxsComponent7 = new HashMap();
        jxsComponent7.put("componentKey", "jfdb");
        jxsComponent7.put("componentValue", jfdb);

        //乙方代表
        Map jxsComponent8 = new HashMap();
        jxsComponent8.put("componentKey", "yfdb");
        jxsComponent8.put("componentValue", yfdb);

        //销售合同明细
        List<Map> xshtmx = new ArrayList<>();
        xshtmx.add(getRowMap(false));
        for (int i = 0; i < xshtmxList.size(); i++) {
            String cpmc = UtilMap.getString(xshtmxList.get(i), "textField_mjb71qa4");//产品名称
            String cpxh = UtilMap.getString(xshtmxList.get(i), "textField_mjb71qa5");//产品型号
            String dw = UtilMap.getString(xshtmxList.get(i), "textField_mjb71qa6");//单位
            String xssl = UtilMap.getString(xshtmxList.get(i), "numberField_mjb71qa7");//销售数量
            double hsdj = UtilMap.getDouble(xshtmxList.get(i), "numberField_mjb71qa8");//含税单价
            int zbq = UtilMap.getInt(xshtmxList.get(i), "numberField_mjb71qaw");//质保期
            String smzs = UtilMap.getString(xshtmxList.get(i), "textField_mjb71qam");//扫描张数
            double jshj = UtilMap.getDouble(xshtmxList.get(i), "numberField_mjb71qan");//价税合计
            double zke = UtilMap.getDouble(xshtmxList.get(i), "numberField_mjb71qao");//折扣额
            String bz = UtilMap.getString(xshtmxList.get(i), "textField_mjb71qaq");//备注

            String zbqValue = zbq > 0 ? zbq + "年" : "";
            if (i == 0){
                xshtmx.add(getRowMap(false,cpmc,cpxh,dw,xssl,hsdj,zbqValue,smzs,jshj,zke,bz));
            }else {
                xshtmx.add(getRowMap(true,cpmc,cpxh,dw,xssl,hsdj,zbqValue,smzs,jshj,zke,bz));
            }
        }
        Map jxsComponent9 = new HashMap();
        jxsComponent9.put("componentKey", "xshtmx");
        jxsComponent9.put("componentValue", JSONObject.toJSONString(xshtmx));

        //甲方
        Map jxsComponent10 = new HashMap();
        jxsComponent10.put("componentKey", "jf2");
        jxsComponent10.put("componentValue", jf);

        //甲方
        Map jxsComponent11 = new HashMap();
        jxsComponent11.put("componentKey", "jf3");
        jxsComponent11.put("componentValue", jf);

        //日期
        Map jxsComponent12 = new HashMap();
        jxsComponent12.put("componentKey", "rq");
        jxsComponent12.put("componentValue", System.currentTimeMillis());


        components.add(jxsComponent);
        components.add(jxsComponent2);
        components.add(jxsComponent3);
        components.add(jxsComponent4);
        components.add(jxsComponent5);
        components.add(jxsComponent7);
        components.add(jxsComponent8);
        components.add(jxsComponent9);
        components.add(jxsComponent10);
        components.add(jxsComponent11);
        components.add(jxsComponent12);

        // 构建请求Body体
        reqBodyObj.put("docTemplateId", qtkh_templateId);
        reqBodyObj.put("fileName", fileName+".pdf");
        reqBodyObj.put("components", components);
    }

    private void getCgddObj(Map formData,List<Map> components,JSONObject reqBodyObj,String fileName){
        String cgddbh = UtilMap.getString(formData, "textField_mj9msq4v");//采购订单编号
        long date = UtilMap.getLong(formData, "dateField_mj8dt3g6");//签订日期
        String yf = UtilMap.getString(formData, "textField_mj8dt3g7");//乙方
        String yfdz = UtilMap.getString(formData, "textField_mj8dt3gt");//乙方地址
        String yflxr = UtilMap.getString(formData, "textField_mj8dt3g8");//乙方联系人
        String yfdh = UtilMap.getString(formData, "textField_mj8dt3g9");//乙方电话
        String nsrsbh = UtilMap.getString(formData, "textField_mj8dt3gs");//乙方纳税人识别号
        String khyh = UtilMap.getString(formData, "textField_mj8dt3gq");//乙方开户银行
        String zh = UtilMap.getString(formData, "textField_mj8dt3gr");//乙方账号
        String zlyq = UtilMap.getString(formData, "textField_mj8dt3gn");//质量要求
        String jsfs = UtilMap.getString(formData, "textField_mj8dt3go");//结算方式及付款期限
        String bz = UtilMap.getString(formData, "textareaField_mj9msq4w");//备注
        List<Map> cgmx = UtilMap.getList(formData, "tableField_mizdd3qf");//采购明细
        double zjyf = UtilMap.getDouble(formData, "numberField_mj9msq4x");//总计应付
        String jflxr = UtilMap.getString(formData, "textField_mjb2kuhf");//甲方联系人
        String jflxdh = UtilMap.getString(formData, "textField_mjb2kuhh");//甲方联系电话

        //订单编号
        Map component = new HashMap();
        component.put("componentKey", "ddbh");
        component.put("componentValue", cgddbh);

        //签订日期
        Map component2 = new HashMap();
        component2.put("componentKey", "qdrq");
        component2.put("componentValue", date);

        //乙方
        Map component3 = new HashMap();
        component3.put("componentKey", "yf");
        component3.put("componentValue", yf);

        //乙方联系人
        Map component4 = new HashMap();
        component4.put("componentKey", "yflxr");
        component4.put("componentValue", yflxr);

        //乙方联系电话
        Map component5 = new HashMap();
        component5.put("componentKey", "yflxdh");
        component5.put("componentValue", yfdh);

        //备注
        Map component6 = new HashMap();
        component6.put("componentKey", "bz");
        component6.put("componentValue", bz);

        //销售合同明细
        List<Map> cghtmx = new ArrayList<>();
        cghtmx.add(getRowMap(false));
        for (int i = 0; i < cgmx.size(); i++) {
            String wlbm = UtilMap.getString(cgmx.get(i), "textField_mizdd3qg");//物料编码
            String wlmc = UtilMap.getString(cgmx.get(i), "textField_mizdd3qh");//物料名称
            String ggxh = UtilMap.getString(cgmx.get(i), "textField_mizdd3qi");//规格型号
            String cgdw = UtilMap.getString(cgmx.get(i), "textField_mizdd3qj");//采购单位
            double cgsl = UtilMap.getDouble(cgmx.get(i), "numberField_mizdd3ql");//采购数量
            double hsdj = UtilMap.getDouble(cgmx.get(i), "numberField_mizdd3qs");//含税单价
            double jshj = UtilMap.getDouble(cgmx.get(i), "numberField_mizdd3qx");//价税合计
            long jhrq = UtilMap.getLong(cgmx.get(i), "dateField_mizdd3qp");//交货日期
            //时间戳转化为年月日
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String jhrqStr = sdf.format(new Date(jhrq));

            String mxbz = UtilMap.getString(cgmx.get(i), "textField_mizdd3r0");//备注

            if (i == 0){
                cghtmx.add(getRowMap(false,i+1,wlbm,wlmc,null,ggxh,cgsl,cgdw,hsdj,jshj,jhrqStr,mxbz));
            }else {
                cghtmx.add(getRowMap(true,i+1,wlbm,wlmc,null,ggxh,cgsl,cgdw,hsdj,jshj,jhrqStr,mxbz));
            }
        }
        Map component7 = new HashMap();
        component7.put("componentKey", "cgmx");
        component7.put("componentValue", JSONObject.toJSONString(cghtmx));

        //总计应付
        Map component8 = new HashMap();
        component8.put("componentKey", "zjyf");
        component8.put("componentValue", zjyf);

        //质量要求
        Map component9 = new HashMap();
        component9.put("componentKey", "zlyq");
        component9.put("componentValue", zlyq);

        //结算方式及付款期限
        Map component10 = new HashMap();
        component10.put("componentKey", "jsfs");
        component10.put("componentValue", jsfs);

        //乙方
        Map component11 = new HashMap();
        component11.put("componentKey", "yf2");
        component11.put("componentValue", yf);

        //乙方开户银行
        Map component12 = new HashMap();
        component12.put("componentKey", "yfkhyh");
        component12.put("componentValue", khyh);

        //乙方账号
        Map component13 = new HashMap();
        component13.put("componentKey", "yfzh");
        component13.put("componentValue", zh);

        //乙方纳税人识别号
        Map component14 = new HashMap();
        component14.put("componentKey", "yfnsrsbh");
        component14.put("componentValue", nsrsbh);

        //乙方地址
        Map component15 = new HashMap();
        component15.put("componentKey", "yfdz");
        component15.put("componentValue", yfdz);

        //甲方联系人
        Map component16 = new HashMap();
        component16.put("componentKey", "jflxr");
        component16.put("componentValue", jflxr);

        //甲方联系电话
        Map component17 = new HashMap();
        component17.put("componentKey", "jflxdh");
        component17.put("componentValue", jflxdh);

        components.add(component);
        components.add(component2);
        components.add(component3);
        components.add(component4);
        components.add(component5);
        components.add(component6);
        components.add(component7);
        components.add(component8);
        components.add(component9);
        components.add(component10);
        components.add(component11);
        components.add(component12);
        components.add(component13);
        components.add(component14);
        components.add(component15);
        components.add(component16);
        components.add(component17);

        // 构建请求Body体
        reqBodyObj.put("docTemplateId", cgdd_templateId);
        reqBodyObj.put("fileName", fileName+".pdf");
        reqBodyObj.put("components", components);
    }

    /***
     * e签宝post请求
     */
    public static Map eqbPost(String postUrl,JSONObject reqBodyObj) {
        // 完整的请求地址
        String postAllUrl = host + postUrl;

        try {
            // 请求Body体数据
            String reqBodyData = reqBodyObj.toString();
            // 对请求Body体内的数据计算ContentMD5
            String contentMD5 = doContentMD5(reqBodyData);
            System.out.println("请求body数据:"+reqBodyData);
            System.out.println("body的md5值："+ contentMD5);

            // 构建待签名字符串
            String method = "POST";
            String accept = "*/*";
            String contentType = "application/json";
            String url = postUrl;
            String date = "";
            String headers = "";

            StringBuffer sb = new StringBuffer();
            sb.append(method).append("\n").append(accept).append("\n").append(contentMD5).append("\n")
                    .append(contentType).append("\n").append(date).append("\n");
            if ("".equals(headers)) {
                sb.append(headers).append(url);
            } else {
                sb.append(headers).append("\n").append(url);
            }

            // 构建参与请求签名计算的明文
            String plaintext = sb.toString();
            // 计算请求签名值
            String reqSignature = doSignatureBase64(plaintext, appKey);
            System.out.println("计算请求签名值:"+reqSignature);

            // 获取时间戳(精确到毫秒)
            long timeStamp = timeStamp();

            // 构建请求头
            LinkedHashMap<String, String> header = new LinkedHashMap<String, String>();
            header.put("X-Tsign-Open-App-Id", appId);
            header.put("X-Tsign-Open-Auth-Mode", "Signature");
            header.put("X-Tsign-Open-Ca-Timestamp", String.valueOf(timeStamp));
            header.put("Accept", accept);
            header.put("Content-Type", contentType);
            header.put("X-Tsign-Open-Ca-Signature", reqSignature);
            header.put("Content-MD5", contentMD5);

            // 发送POST请求
            String result = HTTPHelper.sendPOST(postAllUrl, reqBodyData, header, "UTF-8");

            System.out.println("请求返回信息： " + result);

            Map resultObj =(Map) JSONObject.parse(result);

            Map data = UtilMap.getMap(resultObj, "data");

            return data;
        } catch (Exception e) {
            e.printStackTrace();
            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
            System.out.println(msg);
            throw new RuntimeException(e);
        }
    }

    private Map downloadSignedFile(String signFlowId){
        // 计算签名拼接的url
        String postUrl = "/v3/sign-flow/" + signFlowId + "/file-download-url";

        Map result = eqbPost(postUrl, new JSONObject());

        List<Map> files =(List<Map>) UtilMap.getList(result, "files");

        String downloadUrl = UtilMap.getString(files.get(0), "downloadUrl");
        String fileName = UtilMap.getString(files.get(0), "fileName");
        UUID fileId = UUID.randomUUID();

        String downloadPath = downloadFilePath + fileId + ".pdf";

        downloadFile(downloadUrl,downloadPath);

        Map result2 = new HashMap();
        result2.put("downloadPath",downloadPath);
        result2.put("fileName",fileName);
        result2.put("fileId",fileId);

        return result2;
    }

    //文件下载到本地
    private void downloadFile(String downloadUri,String downloadPath){
        try {
            URL url = new URL(downloadUri);

            HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
            int responseCode = httpConn.getResponseCode();

            // 检查HTTP响应代码是否为200
            if (responseCode == HttpURLConnection.HTTP_OK) {
                InputStream inputStream = httpConn.getInputStream();
                FileOutputStream outputStream = new FileOutputStream(downloadPath);

                byte[] buffer = new byte[4096];
                int bytesRead = -1;

                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }

                outputStream.close();
                inputStream.close();
            } else {
                System.out.println("无法下载文件。HTTP响应代码: " + responseCode);
            }
            httpConn.disconnect();
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }


    /***
     *
     * @param str 待计算的消息
     * @return MD5计算后摘要值的Base64编码(ContentMD5)
     * @throws Exception 加密过程中的异常信息
     */
    public static String doContentMD5(String str) throws Exception {
        byte[] md5Bytes = null;
        MessageDigest md5 = null;
        String contentMD5 = null;
        try {
            md5 = MessageDigest.getInstance("MD5");
            // 计算md5函数
            md5.update(str.getBytes("UTF-8"));
            // 获取文件MD5的二进制数组（128位）
            md5Bytes = md5.digest();
            // 把MD5摘要后的二进制数组md5Bytes使用Base64进行编码（而不是对32位的16进制字符串进行编码）
            contentMD5 = new String(Base64.encodeBase64(md5Bytes), "UTF-8");
        } catch (NoSuchAlgorithmException e) {
            String msg = MessageFormat.format("不支持此算法: {0}", e.getMessage());
            Exception ex = new Exception(msg);
            ex.initCause(e);
            throw ex;
        } catch (UnsupportedEncodingException e) {
            String msg = MessageFormat.format("不支持的字符编码: {0}", e.getMessage());
            Exception ex = new Exception(msg);
            ex.initCause(e);
            throw ex;
        }
        return contentMD5;
    }

    /***
     * 计算请求签名值
     *
     * @param message 待计算的消息
     * @param secret 密钥
     * @return HmacSHA256计算后摘要值的Base64编码
     * @throws Exception 加密过程中的异常信息
     */
    public static String doSignatureBase64(String message, String secret) throws Exception {
        String algorithm = "HmacSHA256";
        Mac hmacSha256;
        String digestBase64 = null;
        try {
            hmacSha256 = Mac.getInstance(algorithm);
            byte[] keyBytes = secret.getBytes("UTF-8");
            byte[] messageBytes = message.getBytes("UTF-8");
            hmacSha256.init(new SecretKeySpec(keyBytes, 0, keyBytes.length, algorithm));
            // 使用HmacSHA256对二进制数据消息Bytes计算摘要
            byte[] digestBytes = hmacSha256.doFinal(messageBytes);
            // 把摘要后的结果digestBytes使用Base64进行编码
            digestBase64 = new String(Base64.encodeBase64(digestBytes), "UTF-8");
        } catch (NoSuchAlgorithmException e) {
            String msg = MessageFormat.format("不支持此算法: {0}", e.getMessage());
            Exception ex = new Exception(msg);
            ex.initCause(e);
            throw ex;
        } catch (UnsupportedEncodingException e) {
            String msg = MessageFormat.format("不支持的字符编码: {0}", e.getMessage());
            Exception ex = new Exception(msg);
            ex.initCause(e);
            throw ex;
        } catch (InvalidKeyException e) {
            String msg = MessageFormat.format("无效的密钥规范: {0}", e.getMessage());
            Exception ex = new Exception(msg);
            ex.initCause(e);
            throw ex;
        }
        return digestBase64;
    }


    /***
     * 获取时间戳(毫秒级)
     *
     * @return 毫秒级时间戳,如 1578446909000
     */
    public static long timeStamp() {
        long timeStamp = System.currentTimeMillis();
        return timeStamp;
    }

    private static Map getRowMap(boolean insertRow,Object... columnValues) {
        Map row = new HashMap();

        for (int i = 0; i < columnValues.length; i++) {
            row.put("column" + (i + 1), columnValues[i]);
        }

        Map result = new HashMap();
        result.put("row",row);
        result.put("insertRow",insertRow);

        return result;
    }
}
