package com.malk.hengyilong.mjavahengyilong;

import com.alibaba.fastjson.JSONObject;
import com.malk.hengyilong.utils.HTTPHelper;
import com.malk.server.common.McR;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.junit.jupiter.api.Test;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.MessageFormat;
import java.util.*;

/**
 * 功能：
 * 作者：hanxue
 * 日期：2026/4/20 16:29
 */
@Slf4j
public class ToEqbTest {


    @Test
    public void main() {
//        // 应用ID
//        String appId = "7439110455";
//        // 应用密钥（AppSecret）
//        String appKey = "ae304291c5702141ea7c98bcdaae6a17";
//        // e签宝接口调用域名（模拟环境）
//        String host = "https://smlopenapi.esign.cn";
////        fileId
//        String fileId ="933318bf1d204d1e8b9816a77ef9e19d";
//        //        docTemplateId
//        String docTemplateId ="ee7bdf1404154c0686ed38a7cf65a7ff";
//        String filecontentMd5 ="nJsZC4SzKUudj0awHel4oQ==";

        // 应用ID
        String appId = "5112061694";
        // 应用密钥（AppSecret）
        String appKey = "7e464621b3aa4a0e39a6557009b38214";
        // e签宝接口调用域名（正式环境）
        String host = "https://openapi.esign.cn";
//           报价单模板文件     fileId
        String fileId ="cacddedc33ff45cea8acd4e8a8f81ac4";
//             报价单模板文件   docTemplateId
        String docTemplateId ="1d2f50e82f514144b72313b1dddcb552";//恒益隆模板id
//        String docTemplateId ="e7440c3f38724b239d7e9dcf7329804a";//绍贺模板id

//             报价单模板文件   filecontentMd5
        String filecontentMd5 ="nJsZC4SzKUudj0awHel4oQ==";

//          购销合同模板文件     fileId
//        String fileId ="c39361f5ca74466a81287f90e94f06c3";
//        //        购销合同模板文件docTemplateId
////        0064564bea704fc587a249680064b98c
////        0cc8c51361444dc7bd39385898893812
////        0064564bea704fc587a249680064b98c
//        String docTemplateId ="d481b2222879447f84d992bac20784d0";
//        //     购销合同模板文件   filecontentMd5
//        String filecontentMd5 ="kPALmlC0o3nU8O6U1HuaxQ==";

        //步骤1：上传本地文件并转成HTML格式
        //1.1获取文件上传地址
//        getFileUploadUrl(appId,appKey,host,filecontentMd5);
        //1.2上传文件流 postman

//
        //步骤2：查看文件上传状态及详情
//        getFileInfo(appId,appKey,host,fileId);
//
        //步骤3：获取制作合同模板页面链接
//        getDocCreateUrl(appId,appKey,host,fileId);
//
//
//        //访问【获取制作合同模板页面】接口返回的创建文件模板页面链接（docTemplateCreateUrl参数值），并在页面中拖动【动态表格】控件来制作模板，若链接失效，调用【获取编辑合同模板页面】接口
//        getDocTemplateEditUrl(appId,appKey,host,docTemplateId);
//
//
//        复制合同模板
//        copyDocTemplate(appId,appKey,host,docTemplateId,"报价单-绍贺");
//        //获取 HTML 模板中控件ID和控件Key
//        getDocTemplateInfo(appId,appKey,host,docTemplateId);
//
        //步骤6：构造数据并填充模板生成文件
        //6.1填写模板生成文件
//        createByDocTemplate(appId,appKey,host,docTemplateId);
//        //6.2开发者使用【查询文件上传状态】接口获取填充后文件链接，通过此链接可查看填充后文件效果
//        253a487cfc1c464190006e7b8532479f
//b97b73a033a341129bf788281a064f43
//        getFileInfo(appId,appKey,host,"cc1106f83a1a40b99e450eb10863bb9d");


        //基于文件发起签署
//        createByFile(appId,appKey,host,"c62b5694b6bc447299ef088146d39111");

//        //查询签署流程详情
//        getSignFlowDetail(appId,appKey,host,"62dc01292d684653bae341adb014b4d0");
//
//        //下载签署文件
//        downloadFile(appId,appKey,host,"8ef134f1e4e648acba2aa0cbe822bd55");

        //查询机构认证信息
        getOrgInfo(appId,appKey,host,"恒益隆贸易（上海）有限公司  ");

//        getOrgUserInfo(appId,appKey,host,"fed0042d62a848de9052de45b31b83ea");

//        getOrgMember(appId,appKey,host,"04dd6dbad3d8456b9e551fc329c516d7");
//        查询个人认证信息
//        getPersonInfo(appId,appKey,host,"13482241481");


        //获取签署地址
//        getSignUrl(appId,appKey,host,"10fa0c28225a45a4ab31d8a7b98cb601","0fd3eb8b0c424b4e827bb3bf1fba62f3");


        // 请求签名鉴权-POST请求
//        testPost(appId, appKey, host);

        // 请求签名鉴权-GET请求
//  String signFlowId = "e622498****ebf72d57dbb";
//  testGet(appId, appKey, host, signFlowId);


    }

    /***
     * 获取文件上传地址
     */
    public static void getFileUploadUrl(String appId, String appKey, String host,String filecontentMd5) {
        // 计算签名拼接的url
        String postUrl = "/v3/files/file-upload-url";
        // 完整的请求地址
        String postAllUrl = host + postUrl;
        try {
            // 构建请求Body体
            JSONObject reqBodyObj = new JSONObject();
            reqBodyObj.put("contentMd5", filecontentMd5);
            reqBodyObj.put("contentType", "application/octet-stream");
            reqBodyObj.put("convertToHTML", true);
//            reqBodyObj.put("fileName", "hengyilong.docx");
//            reqBodyObj.put("fileSize", "24456 ");
            reqBodyObj.put("fileName", "购销合同模板.docx");
            reqBodyObj.put("fileSize", "33095 ");
            // 请求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");
            JSONObject resultObj = JSONObject.parseObject(result);
            System.out.println("请求返回信息： " + resultObj.toString());
        } catch (Exception e) {
            e.printStackTrace();
            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
            System.out.println(msg);
        }
    }

    /***
     * 计算请求Body体的Content-MD5
     * @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();
            // 对Body体MD5的二进制数组(128位）进行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;
    }

    public static long timeStamp() {
        long timeStamp = System.currentTimeMillis();
        return timeStamp;
    }
    /***
     * 计算请求签名值
     *
     * @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;
    }

    /**
     * 查询文件上传状态
     */
    public static void getFileInfo(String appId, String appKey, String host,String fileId) {
        // 计算签名拼接的url
        String getUrl = "/v3/files/"+fileId;
        // 完整的请求地址
        String getAllUrl = host + getUrl;

        try {
            // GET请求时ContentMD5为""
            String contentMD5 = "";

            // 构建待签名字符串
            String method = "GET";
            String accept = "*/*";
            String contentType = "application/json; charset=UTF-8";
            String url = getUrl;
            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-Signature", reqSignature);
            header.put("X-Tsign-Open-Ca-Timestamp", String.valueOf(timeStamp));
            header.put("Accept", accept);
            header.put("Content-Type", contentType);
            header.put("Content-MD5", contentMD5);

            HashMap<String, Object> query = new HashMap<String, Object>();
            // query.put("orgIDCardNum", "9100*****0004");
            // query.put("orgIDCardType", "CRED_ORG_USCC");


            // 发送GET请求
            String result = HTTPHelper.sendGet(getAllUrl, query, header, "UTF-8");
            JSONObject resultObj = JSONObject.parseObject(result);
            System.out.println("请求返回信息： " + resultObj.toString());
        } catch (Exception e) {
            e.printStackTrace();
            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
            System.out.println(msg);
        }
    }
    /***
     * 获取制作合同模板页面
     */
    public static void getDocCreateUrl(String appId, String appKey, String host,String fileId) {
        // 计算签名拼接的url
        String postUrl = "/v3/doc-templates/doc-template-create-url";
        // 完整的请求地址
        String postAllUrl = host + postUrl;


        try {
            // 构建请求Body体
            JSONObject reqBodyObj = new JSONObject();
            reqBodyObj.put("docTemplateName", "购销合同");
            reqBodyObj.put("docTemplateType", 1);
            reqBodyObj.put("fileId", fileId);
//            reqBodyObj.put("hiddenOriginComponents", "false");


            // 请求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");
            JSONObject resultObj = JSONObject.parseObject(result);
            System.out.println("请求返回信息： " + resultObj.toString());
        } catch (Exception e) {
            e.printStackTrace();
            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
            System.out.println(msg);
        }
    }

    /***
     * 获取编辑合同模板页面
     */
    public static void getDocTemplateEditUrl(String appId, String appKey, String host,String docTemplateId) {
        // 计算签名拼接的url
        String postUrl = "/v3/doc-templates/" + docTemplateId + "/doc-template-edit-url";
        // 完整的请求地址
        String postAllUrl = host + postUrl;


        try {
            // 构建请求Body体
            JSONObject reqBodyObj = new JSONObject();

            // 请求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");
            JSONObject resultObj = JSONObject.parseObject(result);
            System.out.println("请求返回信息： " + resultObj.toString());
        } catch (Exception e) {
            e.printStackTrace();
            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
            System.out.println(msg);
        }
    }

    /***
     * 复制合同模板页面
     */
    public static void copyDocTemplate(String appId, String appKey, String host,String docTemplateId,String renameDocTemplate) {
        // 计算签名拼接的url
        String postUrl = "/v3/doc-templates/" + docTemplateId + "/copy";
        // 完整的请求地址
        String postAllUrl = host + postUrl;


        try {
            // 构建请求Body体
            JSONObject reqBodyObj = new JSONObject();
            reqBodyObj.put("renameDocTemplate", renameDocTemplate);

            // 请求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");
            JSONObject resultObj = JSONObject.parseObject(result);
            System.out.println("请求返回信息： " + resultObj.toString());
        } catch (Exception e) {
            e.printStackTrace();
            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
            System.out.println(msg);
        }
    }


    /**
     * 查询合同模板中控件详情
     */
    public static void getDocTemplateInfo(String appId, String appKey, String host,String docTemplateId) {
        // 计算签名拼接的url
        String getUrl = "/v3/doc-templates/"+docTemplateId;
        // 完整的请求地址
        String getAllUrl = host + getUrl;

        try {
            // GET请求时ContentMD5为""
            String contentMD5 = "";

            // 构建待签名字符串
            String method = "GET";
            String accept = "*/*";
            String contentType = "application/json; charset=UTF-8";
            String url = getUrl;
            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-Signature", reqSignature);
            header.put("X-Tsign-Open-Ca-Timestamp", String.valueOf(timeStamp));
            header.put("Accept", accept);
            header.put("Content-Type", contentType);
            header.put("Content-MD5", contentMD5);

            HashMap<String, Object> query = new HashMap<String, Object>();
            // query.put("orgIDCardNum", "9100*****0004");
            // query.put("orgIDCardType", "CRED_ORG_USCC");


            // 发送GET请求
            String result = HTTPHelper.sendGet(getAllUrl, query, header, "UTF-8");
            JSONObject resultObj = JSONObject.parseObject(result);
            System.out.println("请求返回信息： " + resultObj.toString());
        } catch (Exception e) {
            e.printStackTrace();
            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
            System.out.println(msg);
        }
    }

    /***
     * 填写模板生成文件
     */
    public static void createByDocTemplate(String appId, String appKey, String host,String docTemplateId) {
        // 计算签名拼接的url
        String postUrl = "/v3/files/create-by-doc-template";
        // 完整的请求地址
        String postAllUrl = host + postUrl;
        try {
            List<Map> components = new ArrayList<>();

            //我放公司
            Map company = new HashMap();
            company.put("componentKey", "company");
            company.put("componentValue", "上海恒益隆");
            Map companyEng = new HashMap();
            companyEng.put("componentKey", "companyEng");
            companyEng.put("componentValue", "Shanghai");
            Map companySeal = new HashMap();
            companySeal.put("componentKey", "companySeal");
            companySeal.put("componentValue", "上海恒益隆");


            //客户名称
            Map clientName = new HashMap();
            clientName.put("componentKey", "clientName");
            clientName.put("componentValue", "test1");

            //销售人员
            Map salesPerson = new HashMap();
            salesPerson.put("componentKey", "salesPerson");
            salesPerson.put("componentValue", "小韩");

            //联系人
            Map contactPerson = new HashMap();
            contactPerson.put("componentKey", "contactPerson");
            contactPerson.put("componentValue", "小韩");

            //供方联系方式
            Map contactInfo = new HashMap();
            contactInfo.put("componentKey", "contactInfo");
            contactInfo.put("componentValue", "15900010001");

            //需方地址
            Map address = new HashMap();
            address.put("componentKey", "address");
            address.put("componentValue", "上海市浦东新区");

            //供方电子邮箱
            Map email = new HashMap();
            email.put("componentKey", "email");
            email.put("componentValue", "xxx@163.com");

            //客户联系方式
            Map clientContactInfo = new HashMap();
            clientContactInfo.put("componentKey", "clientContactInfo");
            clientContactInfo.put("componentValue", "15252133552");


//          报价日期
            Map quotationDate = new HashMap();
            quotationDate.put("componentKey", "quotationDate");
            quotationDate.put("componentValue", "2026-04-02");

            //客户邮箱
            Map clientEmail = new HashMap();
            clientEmail.put("componentKey", "clientEmail");
            clientEmail.put("componentValue", "xxx@qq.com");

            //有效期
            Map validityPeriod = new HashMap();
            validityPeriod.put("componentKey", "validityPeriod");
            validityPeriod.put("componentValue", "2026-11-02");


            //产品明细
            List<Map> productDetail = new ArrayList<>();
            productDetail.add(getRowMap(false));
            productDetail.add(getRowMap(false,"产品1","型号1","单位1","1.12","1.10","1"));
            productDetail.add(getRowMap(true,"产品2","型号2","单位2","2.12","2.10","2"));
            productDetail.add(getRowMap(true,"产品3","型号3","单位3","3.12","4.10","3"));
            productDetail.add(getRowMap(true,"产品4","型号4","单位4","4.12","4.10","4"));
            productDetail.add(getRowMap(true,"产品5","型号5","单位5","5.12","5.10","5"));
            productDetail.add(getRowMap(true,"产品6","型号6","单位6","6.12","6.10","6"));
            productDetail.add(getRowMap(true,"产品7","型号7","单位7","7.12","7.10","7"));
            productDetail.add(getRowMap(true,"产品8","型号8","单位8","8.12","8.10","8"));

            Map productDetailMap = new HashMap();
            productDetailMap.put("componentKey", "productDetail");
            productDetailMap.put("componentValue", JSONObject.toJSONString(productDetail));


            components.add(company);
            components.add(companyEng);
            components.add(companySeal);
            components.add(clientName);
            components.add(salesPerson);
            components.add(contactPerson);
            components.add(contactInfo);
            components.add(address);
            components.add(email);
            components.add(clientContactInfo);
            components.add(quotationDate);
            components.add(clientEmail);
            components.add(validityPeriod);
            components.add(productDetailMap);


            // 构建请求Body体
            JSONObject reqBodyObj = new JSONObject();
            reqBodyObj.put("docTemplateId", docTemplateId);
            reqBodyObj.put("fileName", "测试报价单-恒益隆.pdf");
            reqBodyObj.put("components", components);

            // 请求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");
            JSONObject resultObj = JSONObject.parseObject(result);
            System.out.println("请求返回信息： " + resultObj.toString());
        } catch (Exception e) {
            e.printStackTrace();
            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
            System.out.println(msg);
        }
    }


    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;
    }

    /***
     * 基于文件发起签署
     */
    public static void createByFile(String appId, String appKey, String host,String fileId) {
        // 计算签名拼接的url
        String postUrl = "/v3/sign-flow/create-by-file";
        // 完整的请求地址
        String postAllUrl = host + postUrl;


        try {
            // 构建请求Body体
            JSONObject reqBodyObj = new JSONObject();
            //设置待签署文件信息
            Map docs = new HashMap();
            docs.put("fileId", fileId);
            reqBodyObj.put("docs", Arrays.asList(docs));

            //签署流程配置项
            Map signFlowConfig = new HashMap();
            signFlowConfig.put("signFlowTitle","测试文件发起签署流程");
            signFlowConfig.put("autoFinish",true);
//            signFlowConfig.put("notifyUrl","https://33d4c762.r23.cpolar.top/huagao/eqb/callback");//回调地址
            reqBodyObj.put("signFlowConfig",signFlowConfig);

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

            Map orgSignerInfo = new HashMap();
            orgSignerInfo.put("orgId","04dd6dbad3d8456b9e551fc329c516d7");
            //企业/机构经办人信息
            Map transactorInfo = new HashMap();
            transactorInfo.put("psnId","c086503ade9a4a3aba83f69c07b14178");//test
            orgSignerInfo.put("transactorInfo",transactorInfo);
            signer.put("orgSignerInfo",orgSignerInfo);

            /*Map psnSignerInfo = new HashMap();
            psnSignerInfo.put("psnId","0fd3eb8b0c424b4e827bb3bf1fba62f3");//wzy
            signer.put("psnSignerInfo",psnSignerInfo);*/

            Map signField = new HashMap();
            signField.put("fileId",fileId);
            signField.put("customBizNum","ydformInstId");
            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));

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



            //reqBodyObj.put("convertToHTML", "false");

            // 请求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");
            JSONObject resultObj = JSONObject.parseObject(result);
            System.out.println("请求返回信息： " + resultObj.toString());
        } catch (Exception e) {
            e.printStackTrace();
            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
            System.out.println(msg);
        }
    }

    /**
     * 查询机构认证信息
     */
    public static void getOrgInfo(String appId, String appKey, String host,String orgName) {
        try {
            // 计算签名拼接的url
            //urlencode转码
            String orgNameEncode = URLEncoder.encode(orgName,"UTF-8");
            String getUrl = "/v3/organizations/identity-info?orgName="+orgName;
            // 完整的请求地址
            String getAllUrl = host + "/v3/organizations/identity-info?orgName="+orgNameEncode;

            // GET请求时ContentMD5为""
            String contentMD5 = "";

            // 构建待签名字符串
            String method = "GET";
            String accept = "*/*";
            String contentType = "application/json; charset=UTF-8";
            String url = getUrl;
            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-Signature", reqSignature);
            header.put("X-Tsign-Open-Ca-Timestamp", String.valueOf(timeStamp));
            header.put("Accept", accept);
            header.put("Content-Type", contentType);
            header.put("Content-MD5", contentMD5);

            System.out.println(header);

            HashMap<String, Object> query = new HashMap<String, Object>();
//             query.put("orgName", orgName);
            // query.put("orgIDCardType", "CRED_ORG_USCC");


            // 发送GET请求
            String result = HTTPHelper.sendGet(getAllUrl, query, header, "UTF-8");
            JSONObject resultObj = JSONObject.parseObject(result);
            System.out.println("请求返回信息： " + resultObj.toString());
        } catch (Exception e) {
            e.printStackTrace();
            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
            System.out.println(msg);
        }
    }

    /**
     * 查询企业用户授权详情
     */
    public static void getOrgUserInfo(String appId, String appKey, String host,String orgId) {
        // 计算签名拼接的url
        String getUrl = "/v3/organizations/"+orgId+"/authorized-info";
        // 完整的请求地址
        String getAllUrl = host + getUrl;

        try {
            // GET请求时ContentMD5为""
            String contentMD5 = "";

            // 构建待签名字符串
            String method = "GET";
            String accept = "*/*";
            String contentType = "application/json; charset=UTF-8";
            String url = getUrl;
            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-Signature", reqSignature);
            header.put("X-Tsign-Open-Ca-Timestamp", String.valueOf(timeStamp));
            header.put("Accept", accept);
            header.put("Content-Type", contentType);
            header.put("Content-MD5", contentMD5);

            HashMap<String, Object> query = new HashMap<String, Object>();
//             query.put("orgName", orgName);
            // query.put("orgIDCardType", "CRED_ORG_USCC");


            // 发送GET请求
            String result = HTTPHelper.sendGet(getAllUrl, query, header, "UTF-8");
            JSONObject resultObj = JSONObject.parseObject(result);
            System.out.println("请求返回信息： " + resultObj.toString());
        } catch (Exception e) {
            e.printStackTrace();
            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
            System.out.println(msg);
        }
    }

    /***
     * 查询企业成员列表
     */
    public static void getOrgMember(String appId, String appKey, String host,String orgId) {
        // 计算签名拼接的url
        String getUrl = "/v3/organizations/"+orgId+"/member-list?pageNum=1&pageSize=100";
        // 完整的请求地址
        String getAllUrl = host + getUrl;

        try {
            // GET请求时ContentMD5为""
            String contentMD5 = "";

            // 构建待签名字符串
            String method = "GET";
            String accept = "*/*";
            String contentType = "application/json; charset=UTF-8";
            String url = getUrl;
            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-Signature", reqSignature);
            header.put("X-Tsign-Open-Ca-Timestamp", String.valueOf(timeStamp));
            header.put("Accept", accept);
            header.put("Content-Type", contentType);
            header.put("Content-MD5", contentMD5);

            HashMap<String, Object> query = new HashMap<String, Object>();
            // query.put("orgIDCardNum", "9100*****0004");
            // query.put("orgIDCardType", "CRED_ORG_USCC");


            // 发送GET请求
            String result = HTTPHelper.sendGet(getAllUrl, query, header, "UTF-8");
            JSONObject resultObj = JSONObject.parseObject(result);
            System.out.println("请求返回信息： " + resultObj.toString());
        } catch (Exception e) {
            e.printStackTrace();
            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
            System.out.println(msg);
        }
    }

    /***
     * 查询个人认证信息
     */
    public static void getPersonInfo(String appId, String appKey, String host,String psnAccount) {
        // 计算签名拼接的url
        String getUrl = "/v3/persons/identity-info"+"?psnAccount="+psnAccount;
        // 完整的请求地址
        String getAllUrl = host + getUrl;

        try {
            // GET请求时ContentMD5为""
            String contentMD5 = "";

            // 构建待签名字符串
            String method = "GET";
            String accept = "*/*";
            String contentType = "application/json; charset=UTF-8";
            String url = getUrl;
            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-Signature", reqSignature);
            header.put("X-Tsign-Open-Ca-Timestamp", String.valueOf(timeStamp));
            header.put("Accept", accept);
            header.put("Content-Type", contentType);
            header.put("Content-MD5", contentMD5);

            HashMap<String, Object> query = new HashMap<String, Object>();
            // query.put("orgIDCardNum", "9100*****0004");
            // query.put("orgIDCardType", "CRED_ORG_USCC");


            // 发送GET请求
            String result = HTTPHelper.sendGet(getAllUrl, query, header, "UTF-8");
            JSONObject resultObj = JSONObject.parseObject(result);
            System.out.println("请求返回信息： " + resultObj.toString());
        } catch (Exception e) {
            e.printStackTrace();
            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
            System.out.println(msg);
        }
    }


    /***
     * 下载已签署文件及附属材料
     */
    public static void downloadFile(String appId, String appKey, String host,String signFlowId) {
        // 计算签名拼接的url
        String postUrl = "/v3/sign-flow/" + signFlowId + "/file-download-url";
        // 完整的请求地址
        String postAllUrl = host + postUrl;


        try {
            // 构建请求Body体
            JSONObject reqBodyObj = new JSONObject();

            // 请求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");
            JSONObject resultObj = JSONObject.parseObject(result);
            System.out.println("请求返回信息： " + resultObj.toString());
        } catch (Exception e) {
            e.printStackTrace();
            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
            System.out.println(msg);
        }
    }




}
