package com.malk.huagao;
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.*;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import com.alibaba.fastjson.JSON;
import com.malk.huagao.utils.HTTPHelper;
import org.apache.commons.codec.binary.Base64;
import com.alibaba.fastjson.JSONObject;

public class EqbTest {


    public static void main(String[] args) {


        /*String responseBody = "[{\"code\":200,\"msg\":\"销售订单编码：DD202601280002单据同步成功\",\"data\":{\"djbh\":\"DD202601280002\"}}]";
        System.out.println("响应内容: " + responseBody);

        try {
            // 一行代码提取
            String djbh = JSON.parseArray(responseBody)
                    .getJSONObject(0)
                    .getJSONObject("data")
                    .getString("djbh");

            System.out.println("提取的djbh: " + djbh);

        } catch (Exception e) {
            System.out.println("解析JSON失败: " + e.getMessage());
        }*/


        // 应用ID
        /*String appId = "7439093376";
        // 应用密钥（AppSecret）
        String appKey = "0589e55190dfd861d29a2313ce0b6f56";
        // e签宝接口调用域名（模拟环境）
        String host = "https://smlopenapi.esign.cn";*/


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


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

        //步骤2：查看文件上传状态及详情
//        getFileInfo(appId,appKey,host,"1c2ede25c6454ad4af8bcba3dd9beb35");

        //步骤3：获取制作合同模板页面链接
//        getDocCreateUrl(appId,appKey,host,"418d535ab69f4c1fbe01931b8b74f82f");

        //测试环境模板id ef7d3bcee4254e67944d53db6a1f76eb

        //正式环境模板id 经销商模板：6a23f76742d74b858cdc2259a5d5c32f
        //正式环境模板id 其他客户模板：8b7fef2257bc4093ada330dbf7c874c5
        //正式环境模板id 采购订单模板：a0827f8946994ebfbed7f44e6b8a6ed8

        //步骤4：制作含动态表格控件的HTML模板 访问【获取制作合同模板页面】接口返回的创建文件模板页面链接（docTemplateCreateUrl参数值），并在页面中拖动【动态表格】控件来制作模板，若链接失效，调用【获取编辑合同模板页面】接口
        getDocTemplateEditUrl(appId,appKey,host,"8b7fef2257bc4093ada330dbf7c874c5");


        //步骤5：获取 HTML 模板中控件ID和控件Key
//        getDocTemplateInfo(appId,appKey,host,"6a23f76742d74b858cdc2259a5d5c32f");

        //步骤6：构造数据并填充模板生成文件
        //6.1填写模板生成文件
//        createByDocTemplate(appId,appKey,host,"6a23f76742d74b858cdc2259a5d5c32f");
        //6.2开发者使用【查询文件上传状态】接口获取填充后文件链接，通过此链接可查看填充后文件效果
//        getFileInfo(appId,appKey,host,"28e65af0dd3a4f989da68d14bcd06373");


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

        //查询签署流程详情
//        getSignFlowDetail(appId,appKey,host,"62dc01292d684653bae341adb014b4d0");

        //下载签署文件
//        downloadFile(appId,appKey,host,"9dbc4ddfbaba477084f046fc095032e6");

        //查询机构认证信息（暂不使用 鉴权失败）
//        getOrgInfo(appId,appKey,host,"宁波华高信息科技有限公司");

//        getOrgUserInfo(appId,appKey,host,"00739a62731c498a8ecf477bf79efc54");

//        getOrgMember(appId,appKey,host,"a5ec8fb7d8cc4276bd486824df0ec640");


        //获取签署地址
//        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) {
        // 计算签名拼接的url
        String postUrl = "/v3/files/file-upload-url";
        // 完整的请求地址
        String postAllUrl = host + postUrl;


        try {
            // 构建请求Body体
            JSONObject reqBodyObj = new JSONObject();
            reqBodyObj.put("contentMd5", "iyxiNd3iJ7A+QFE9fAUqvQ==");
            reqBodyObj.put("contentType", "application/octet-stream");
//            reqBodyObj.put("convertToPDF", "true");
            reqBodyObj.put("convertToHTML", true);
            reqBodyObj.put("fileName", "其他客户销售合同.docx");
            reqBodyObj.put("fileSize", "28246");
            //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 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 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 component = new HashMap();
            component.put("componentKey", "dgdbh");
            component.put("componentValue", "ABC0001");

            //需方
            Map component2 = new HashMap();
            component2.put("componentKey", "xf");
            component2.put("componentValue", "测试XX公司");

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

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

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

            //订单日期
            Map component6 = new HashMap();
            component6.put("componentKey", "ddrq");
            component6.put("componentValue", "2025年12月12日");

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

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



            Map component8 = new HashMap();
            component8.put("componentKey", "xshtmx");
            component8.put("componentValue", JSONObject.toJSONString(xshtmx));

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

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

            //先款后货
            Map component11 = new HashMap();
            component11.put("componentKey", "xkhh");
            component11.put("componentValue", true);

            //交货地址
            List<Map> jhdz = new ArrayList<>();
            jhdz.add(getRowMap(false));
            jhdz.add(getRowMap(false,"1","地址1","收货人1","联系电话1"));
            jhdz.add(getRowMap(true,"2","地址2","收货人2","联系电话2"));
            jhdz.add(getRowMap(true,"3","地址3","收货人3","联系电话3"));
            jhdz.add(getRowMap(true,"4","地址4","收货人4","联系电话4"));

            Map component12 = new HashMap();
            component12.put("componentKey", "jhdz");
            component12.put("componentValue", JSONObject.toJSONString(jhdz));

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

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

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

            //需方2
            Map component16 = new HashMap();
            component16.put("componentKey", "xf2");
            component16.put("componentValue", "测试XX公司");

            //需方地址2
            Map component17 = new HashMap();
            component17.put("componentKey", "xfdz2");
            component17.put("componentValue", "测试地址");

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

    /***
     * 基于文件发起签署
     */
    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","a5ec8fb7d8cc4276bd486824df0ec640");
            //企业/机构经办人信息
            Map transactorInfo = new HashMap();
            transactorInfo.put("psnId","0fd3eb8b0c424b4e827bb3bf1fba62f3");//wzy
            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 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 getSignFlowDetail(String appId, String appKey, String host,String signFlowId) {
        // 计算签名拼接的url
        String getUrl = "/v3/sign-flow/"+signFlowId+"/detail";
        // 完整的请求地址
        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);
        }
    }


    /***
     * 获取签署页面链接
     */
    public static void getSignUrl(String appId, String appKey, String host,String signFlowId,String psnId) {
        // 计算签名拼接的url
        String postUrl = "/v3/sign-flow/"+signFlowId+"/sign-url";
        // 完整的请求地址
        String postAllUrl = host + postUrl;


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

            reqBodyObj.put("operator", operator);

            // 请求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);
        }
    }




    /***
     * 请求签名鉴权-POST请求
     *
     * @param appId=应用ID
     * @param appKey=应用密钥（AppSecret）
     * @param host
     */
    public static void testPost(String appId, String appKey, String host) {
        // 计算签名拼接的url
        String postUrl = "/v3/files/file-upload-url";
        // 完整的请求地址
        String postAllUrl = host + postUrl;


        try {
            // 构建请求Body体
            JSONObject reqBodyObj = new JSONObject();
            reqBodyObj.put("contentMd5", "KMYh+0qU9/FDXf2TwCGbeg==");
            reqBodyObj.put("contentType", "application/octet-stream");
            reqBodyObj.put("convertToPDF", "true");
            reqBodyObj.put("fileName", "销售合同.docx");
            reqBodyObj.put("fileSize", "81825");
            //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 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);
        }
    }


    /***
     * 请求签名鉴权-GET请求
     *
     * @param appId=应用ID
     * @param appKey=应用密钥（AppSecret）
     * @param host
     */

    public static void testGet(String appId, String appKey, String host,String signFlowId) {
        // 计算签名拼接的url
        String getUrl = "/v3/sign-flow/"+signFlowId+"/detail";
        // 完整的请求地址
        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);
        }
    }

    /***
     *
     * @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;
    }
}
