package com.malk.hengyilong.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.malk.hengyilong.service.EqbHylService;
import com.malk.hengyilong.utils.HTTPHelper;
import com.malk.server.aliwork.YDConf;
import com.malk.server.aliwork.YDParam;
import com.malk.server.aliwork.YDSearch;
import com.malk.server.common.McR;
import com.malk.service.aliwork.YDClient;
import com.malk.utils.UtilMap;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.MessageFormat;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 功能：
 * 作者：hanxue
 * 日期：2026/4/24 18:04
 */
@Service
public class EqbHylServiceImpl implements EqbHylService {
    @Autowired
    private YDClient ydClient;
    @Value("${eqb.appId}")
    private String appId;
    @Value("${eqb.appKey}")
    private String appKey;
    @Value("${eqb.host}")
    private String host;
    @Value("${eqb.orgIdSh}")
    private String orgIdSh;
    @Value("${eqb.orgIdHyl}")
    private String orgIdHyl;
    @Value("${eqb.psnId}")
    private String psnId;
    @Value("${server.host}")
    private String serverHost;

    private static String bjdHYL_docTemplateId ="1d2f50e82f514144b72313b1dddcb552";
    private static String bjdSH_docTemplateId ="e7440c3f38724b239d7e9dcf7329804a";

    private static String ht_docTemplateId ="d481b2222879447f84d992bac20784d0";

//    测试报价单模板ID：ee7bdf1404154c0686ed38a7cf65a7ff
//    正式报价单模板ID：1d2f50e82f514144b72313b1dddcb552
//    正式合同模板ID：0064564bea704fc587a249680064b98c
//    正式合同新模板ID：d481b2222879447f84d992bac20784d0

    @Override
    public McR quotationToEqb(Map map) {
//        1、获取宜搭报价单数据
        String formInstance = UtilMap.getString(map, "formInstance");
        Map formData = ydClient.queryData(YDParam.builder()
                .formInstanceId(formInstance)
                .build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
        System.out.println(formData);
        try {
//        2、根据模板填充报价单数据
            String reportType = UtilMap.getString(map, "type");

            JSONObject reqBodyObj = new JSONObject();
            List<Map> components = new ArrayList<>();
            boolean shouldExecutePost = false;
            String fileName="";
            switch (reportType){
                case "quotation":
                    fileName = UtilMap.getString(formData, "textField_mn5mis1m");
                    getQuotation(formData, components, reqBodyObj, fileName);
                    shouldExecutePost = true;
                    break;
                case "contract":
                    String signStatus = UtilMap.getString(formData, "radioField_mkcbpvh8");
                    fileName = UtilMap.getString(formData, "textField_mjmlcp4s");
                    if ("我方模版".equals(signStatus)) {
                        getContract(formData, components, reqBodyObj, fileName);
                        // 只有满足“我方模版”条件，才打开开关
                        shouldExecutePost = true;
                    }
                    break;
                default:break;
            }
            // 直接退出当前方法，不再执行下面的 eqbPost
            if (!shouldExecutePost) {
                return McR.success("购销模板需要客户模板，无需发起签署");
            }
            Map fileResult = eqbPost("/v3/files/create-by-doc-template", reqBodyObj);
            String fileId = UtilMap.getString(fileResult,"fileId");
//            文档转换pdf需时间--否则文档未成功转换成pdf
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
//        3、基于生成文件发起签署
            JSONObject reqBodyObjSign = new JSONObject();
            //3.1设置待签署文件信息
            Map docs = new HashMap();
            docs.put("fileId", fileId);
            reqBodyObjSign.put("docs", Arrays.asList(docs));
//            3.2设置签署流程配置项
            Map signFlowConfig = new HashMap();
            signFlowConfig.put("signFlowTitle",fileName);
            signFlowConfig.put("autoFinish",true);
            signFlowConfig.put("notifyUrl",serverHost+"/hengyilong/callback");

            reqBodyObjSign.put("signFlowConfig",signFlowConfig);
//             3.3设置签署参与方
//            3.3.1设置我方签署信息
            Map signer = new HashMap();
            signer.put("signerType",1);//签署方类型，0 - 个人，1 - 企业/机构，2 - 法定代表人，3 - 经办人
            signer.put("signConfig",UtilMap.map("signOrder",1));
            Map orgSignerInfo = new HashMap();
            //企业/机构账号ID
            if ("恒益隆贸易(上海)有限公司".equals(UtilMap.getString(formData, "selectField_mjmlcp4y"))) {
                orgSignerInfo.put("orgId",orgIdHyl);
            }else  if ("上海绍贺贸易有限公司".equals(UtilMap.getString(formData, "selectField_mjmlcp4y"))){
                orgSignerInfo.put("orgId",orgIdSh);
            }
            //经办人信息
            Map transactorInfo = new HashMap();
            transactorInfo.put("psnId",psnId);//经办人id
            orgSignerInfo.put("transactorInfo",transactorInfo);
            signer.put("orgSignerInfo",orgSignerInfo);

            Map signField = new HashMap();
            signField.put("fileId",fileId);
            signField.put("customBizNum",formInstance);
//            签章区配置项
            Map normalSignFieldConfig = new HashMap();
            normalSignFieldConfig.put("freeMode",true);
            signField.put("normalSignFieldConfig",normalSignFieldConfig);
            signer.put("signFields",Arrays.asList(signField));

            List<Map> signersList = new ArrayList<>();
            signersList.add(signer);
//            3.3.2设置对方签署信息
            if("需要".equals(UtilMap.getString(formData, "radioField_mqejx60u"))){
                Map otherSigner = new HashMap();
                otherSigner.put("signerType",1);//签署方类型，0 - 个人，1 - 企业/机构，2 - 法定代表人，3 - 经办人
                otherSigner.put("signConfig",UtilMap.map("signOrder",2));
                Map otherOrgSignerInfo = new HashMap();
                //企业/机构账号名称
                otherOrgSignerInfo.put("orgName",UtilMap.getString(formData, "textField_mqejx60w"));
                otherOrgSignerInfo.put("orgInfo",UtilMap.map("orgIDCardNum, orgIDCardType",UtilMap.getString(formData, "textField_mqejx60x"),"CRED_ORG_USCC"));
                //经办人信息
                Map otherTransactorInfo = new HashMap();
                otherTransactorInfo.put("psnAccount",UtilMap.getString(formData, "textField_mqejx60y"));//经办人账号标识，手机号或邮箱，必须配合psnName（经办人姓名）传入
                otherTransactorInfo.put("psnInfo",UtilMap.map("psnName",UtilMap.getString(formData, "textField_mqj4ypzj")));//经办人姓名
                otherOrgSignerInfo.put("transactorInfo",otherTransactorInfo);
                otherSigner.put("orgSignerInfo",otherOrgSignerInfo);

                Map otherSignField = new HashMap();
                otherSignField.put("fileId",fileId);
                otherSignField.put("customBizNum",formInstance);
//            签章区配置项
                Map otherSignFieldConfig = new HashMap();
                otherSignFieldConfig.put("freeMode",true);
                otherSignField.put("normalSignFieldConfig",otherSignFieldConfig);
                otherSigner.put("signFields",Arrays.asList(otherSignField));
                signersList.add(otherSigner);
            }
            reqBodyObjSign.put("signers",signersList);
            Map signResult = eqbPost("/v3/sign-flow/create-by-file", reqBodyObjSign);
            String signFlowId = UtilMap.getString(signResult,"signFlowId");

            //4、回写签署地址到宜搭
            JSONObject reqBodyObj3 = new JSONObject();
            Map operator = new HashMap();
            operator.put("psnId", psnId);
            reqBodyObj3.put("operator", operator);
            Map signLink = eqbPost("/v3/sign-flow/" + signFlowId + "/sign-url", reqBodyObj3);
            String shortUrl = UtilMap.getString(signLink, "shortUrl");
            ydClient.operateData(YDParam.builder()
                    .formInstanceId(formInstance)
                    .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("textField_moh0gw9l, textareaField_mqj4ypzk",shortUrl,"成功推送e签宝")))
                    .build(), YDConf.FORM_OPERATION.update);
            return McR.success(shortUrl);

//            return McR.success(fileId);
        } catch (Exception e) {
            ydClient.operateData(YDParam.builder()
                    .formInstanceId(formInstance)
                    .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("textareaField_mqj4ypzk",e.getMessage())))
                    .build(), YDConf.FORM_OPERATION.update);
            return McR.errorParam(e.getMessage());
        }
    }

//    生成报价单模板文件数据
    private static void getQuotation(Map formData,List<Map> components,JSONObject reqBodyObj,String fileName){
        try{
        //客户名称
        Map clientName = new HashMap();
        clientName.put("componentKey", "clientName");
        clientName.put("componentValue",formData.containsKey("textField_mkdmgdot")?UtilMap.getString(formData, "textField_mkdmgdot"):"");
        //需方联系人
        Map contactPerson = new HashMap();
        contactPerson.put("componentKey", "contactPerson");
        contactPerson.put("componentValue",formData.containsKey("textField_ml0iaa3i")?UtilMap.getString(formData, "textField_ml0iaa3i"):"");
        //需方地址
        Map address = new HashMap();
        address.put("componentKey", "address");
        address.put("componentValue",formData.containsKey("textField_mogtxb0g")?UtilMap.getString(formData, "textField_mogtxb0g"):"");
        //客户联系方式
        Map clientContactInfo = new HashMap();
        clientContactInfo.put("componentKey", "clientContactInfo");
        clientContactInfo.put("componentValue",formData.containsKey("textField_ml0iaa3k")?UtilMap.getString(formData, "textField_ml0iaa3k"):"");
        //需方电子邮箱
        Map clientEmail = new HashMap();
        clientEmail.put("componentKey", "clientEmail");
        clientEmail.put("componentValue",formData.containsKey("textField_mogtxb0h")?UtilMap.getString(formData, "textField_mogtxb0h"):"");

        //我方公司
        Map company = new HashMap();
        company.put("componentKey", "company");
        company.put("componentValue", formData.containsKey("selectField_mjmlcp4y")?UtilMap.getString(formData, "selectField_mjmlcp4y"):"");
//            我方公司印章
        Map companySeal = new HashMap();
        companySeal.put("componentKey", "companySeal");
        companySeal.put("componentValue", formData.containsKey("selectField_mjmlcp4y")?UtilMap.getString(formData, "selectField_mjmlcp4y"):"");

        Map companyEng = new HashMap();
        if ("恒益隆贸易(上海)有限公司".equals(UtilMap.getString(formData, "selectField_mjmlcp4y"))) {
            companyEng.put("componentKey", "companyEng");
            companyEng.put("componentValue", "Wells International Trading (Shanghai) Co.,Ltd");
        }else  if ("上海绍贺贸易有限公司".equals(UtilMap.getString(formData, "selectField_mjmlcp4y"))){
            companyEng.put("componentKey", "companyEng");
            companyEng.put("componentValue", "Shanghai Shaw He Enterprise Co.,Ltd");
        }
        //销售人员
        Map salesPerson = new HashMap();
        salesPerson.put("componentKey", "salesPerson");
        salesPerson.put("componentValue", formData.containsKey("employeefield_3VMLhM35")?UtilMap.getList(formData, "employeefield_3VMLhM35").get(0):"");
        //供方联系方式
        Map contactInfo = new HashMap();
        contactInfo.put("componentKey", "contactInfo");
        contactInfo.put("componentValue",formData.containsKey("textField_mogubh6s")?UtilMap.getString(formData, "textField_mogubh6s"):"");
        //供方电子邮箱
        Map email = new HashMap();
        email.put("componentKey", "email");
        email.put("componentValue",formData.containsKey("textField_mogubh6t")?UtilMap.getString(formData, "textField_mogubh6t"):"");
        //报价日期
        Map quotationDate = new HashMap();
        if(formData.containsKey("dateField_mjmkwpsf")){
            long quotationTimestamp = UtilMap.getLong(formData, "dateField_mjmkwpsf"); // 例如对应 2026-04-27
            String quotationDateStr = Instant.ofEpochMilli(quotationTimestamp)
                    .atZone(ZoneId.systemDefault())
                    .format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            quotationDate.put("componentKey", "quotationDate");
            quotationDate.put("componentValue", quotationDateStr);
        }else{
            quotationDate.put("componentKey", "quotationDate");
            quotationDate.put("componentValue", "");

        }

        //有效期
        Map validityPeriod = new HashMap();
        if(formData.containsKey("datefield_SBfn4X3p")){
            long validityTimestamp = UtilMap.getLong(formData, "datefield_SBfn4X3p"); // 例如对应 2026-04-27
            String validityPeriodStr = Instant.ofEpochMilli(validityTimestamp)
                    .atZone(ZoneId.systemDefault())
                    .format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            validityPeriod.put("componentKey", "validityPeriod");
            validityPeriod.put("componentValue", validityPeriodStr);
        }else{
            validityPeriod.put("componentKey", "validityPeriod");
            validityPeriod.put("componentValue", "");
        }
        // 产品明细
        List<Map> productTable = UtilMap.getList(formData, "tableField_mkdl67qc");
        List<Map> productDetail = new ArrayList<>();
        productDetail.add(getRowMap(false));
        for (int i = 0; i < productTable.size(); i++) {
            String productType = productTable.get(i).containsKey("selectField_mq6g5d7h")?UtilMap.getString(productTable.get(i), "selectField_mq6g5d7h"):"";//产品类型
            String productName = productTable.get(i).containsKey("textField_mq505rze")?UtilMap.getString(productTable.get(i), "textField_mq505rze"):"";//产品名称
//            String productModel = productTable.get(i).containsKey("textField_mogxdk7x")?UtilMap.getString(productTable.get(i), "textField_mogxdk7x"):"";//产品型号--舍弃
            String productSize = productTable.get(i).containsKey("textField_mogxdk7y")?UtilMap.getString(productTable.get(i), "textField_mogxdk7y"):"";//产品规格
            String productNum = productTable.get(i).containsKey("numberField_mkdl67qd")?UtilMap.getString(productTable.get(i), "numberField_mkdl67qd"):"";//数量
            String productUnit = productTable.get(i).containsKey("textField_mq6g5d7g")?UtilMap.getString(productTable.get(i), "textField_mq6g5d7g"):"";//单位
            double productPrice = productTable.get(i).containsKey("numberField_mkdl67qe")?UtilMap.getDouble(productTable.get(i), "numberField_mkdl67qe"):0;//单价
            String note = productTable.get(i).containsKey("textField_mkdl67qg")?UtilMap.getString(productTable.get(i), "textField_mkdl67qg"):"";//备注
            if ("恒益隆贸易(上海)有限公司".equals(UtilMap.getString(formData, "selectField_mjmlcp4y"))) {
                if (i == 0){
                    productDetail.add(getRowMap(false,productType,productName,productSize,productNum,productUnit,productPrice,note));
                }else {
                    productDetail.add(getRowMap(true,productType,productName,productSize,productNum,productUnit,productPrice,note));
                }
            }else  if ("上海绍贺贸易有限公司".equals(UtilMap.getString(formData, "selectField_mjmlcp4y"))){
                if (i == 0){
                    productDetail.add(getRowMap(false,productName,productSize,productNum,productUnit,productPrice,note));
                }else {
                    productDetail.add(getRowMap(true,productName,productSize,productNum,productUnit,productPrice,note));
                }
            }
        }
        Map productDetailMap = new HashMap();
        productDetailMap.put("componentKey", "productDetail");
        productDetailMap.put("componentValue", JSONObject.toJSONString(productDetail));

            //交货方式
        Map submitType = new HashMap();
        submitType.put("componentKey", "submitType");
        submitType.put("componentValue", formData.containsKey("textField_mogtxb0m")?UtilMap.getString(formData, "textField_mogtxb0m"):"");
        //付款方式
        Map payType = new HashMap();
        payType.put("componentKey", "payType");
        payType.put("componentValue", formData.containsKey("textField_mogtxb0o")?UtilMap.getString(formData, "textField_mogtxb0o"):"");
        //送货日期
        Map deliverDate = new HashMap();
        deliverDate.put("componentKey", "deliverDate");
        deliverDate.put("componentValue", formData.containsKey("textField_mogtxb0q")?UtilMap.getString(formData, "textField_mogtxb0q"):"");


        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);
        components.add(company);
        components.add(companyEng);
        components.add(companySeal);
        components.add(submitType);
        components.add(payType);
        components.add(deliverDate);
        if ("恒益隆贸易(上海)有限公司".equals(UtilMap.getString(formData, "selectField_mjmlcp4y"))) {
            reqBodyObj.put("docTemplateId", bjdHYL_docTemplateId);
        }else  if ("上海绍贺贸易有限公司".equals(UtilMap.getString(formData, "selectField_mjmlcp4y"))){
            reqBodyObj.put("docTemplateId", bjdSH_docTemplateId);
        }
        reqBodyObj.put("fileName", fileName+".pdf");
        reqBodyObj.put("components", components);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    //    生成合同订单模板文件数据
    private static void getContract(Map formData,List<Map> components,JSONObject reqBodyObj,String fileName){
        try{
            //我方公司
            Map companyTitle = new HashMap();
            companyTitle.put("componentKey", "companyTitle");
            companyTitle.put("componentValue", formData.containsKey("selectField_mjmlcp4y")?UtilMap.getString(formData, "selectField_mjmlcp4y"):"");

            //我方公司英文
            Map companyEng = new HashMap();
            if ("恒益隆贸易(上海)有限公司".equals(UtilMap.getString(formData, "selectField_mjmlcp4y"))) {
                companyEng.put("componentKey", "companyEng");
                companyEng.put("componentValue", "Wells International Trading (Shanghai) Co.,Ltd");
            }else  if ("上海绍贺贸易有限公司".equals(UtilMap.getString(formData, "selectField_mjmlcp4y"))){
                companyEng.put("componentKey", "companyEng");
                companyEng.put("componentValue", "Shanghai Shaw He Enterprise Co.,Ltd");
            }

            //供方
            Map supplier = new HashMap();
            supplier.put("componentKey", "supplier");
            supplier.put("componentValue", formData.containsKey("selectField_mjmlcp4y")?UtilMap.getString(formData, "selectField_mjmlcp4y"):"");
            //送货地址
            Map productAddress = new HashMap();
            productAddress.put("componentKey", "productAddress");
            productAddress.put("componentValue", formData.containsKey("textareaField_ml3g7xro")?UtilMap.getString(formData, "textareaField_ml3g7xro"):"");

            //需方
            Map buyer = new HashMap();
            buyer.put("componentKey", "buyer");
            buyer.put("componentValue", formData.containsKey("textField_mkkr6eru")?UtilMap.getString(formData, "textField_mkkr6eru"):"");

            //合同编号
            Map contractNo = new HashMap();
            contractNo.put("componentKey", "contractNo");
            contractNo.put("componentValue", formData.containsKey("textfield_AevzfRIt")?UtilMap.getString(formData, "textfield_AevzfRIt"):"");

            //签订日期
            Map signDate = new HashMap();
            if(formData.containsKey("datefield_oEfE9lwc")){
                long quotationTimestamp = UtilMap.getLong(formData, "datefield_oEfE9lwc"); // 例如对应 2026-04-27
                String signDateStr = Instant.ofEpochMilli(quotationTimestamp)
                        .atZone(ZoneId.systemDefault())
                        .format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                signDate.put("componentKey", "signDate");
                signDate.put("componentValue", signDateStr);
            }else{
                signDate.put("componentKey", "signDate");
                signDate.put("componentValue", "");
            }

            //签订地址
            Map signAddress = new HashMap();
            signAddress.put("componentKey", "signAddress");
            signAddress.put("componentValue", formData.containsKey("textField_mp5c1fkv")?UtilMap.getString(formData, "textField_mp5c1fkv"):"");

            //我方公司名称
            Map companyName = new HashMap();
            companyName.put("componentKey", "companyName");
            companyName.put("componentValue", formData.containsKey("selectField_mjmlcp4y")?UtilMap.getString(formData, "selectField_mjmlcp4y"):"");

            //供方签约代表人
            Map supplySignatory = new HashMap();
            supplySignatory.put("componentKey", "supplySignatory");
            supplySignatory.put("componentValue", formData.containsKey("employeefield_3VMLhM35")?UtilMap.getList(formData, "employeefield_3VMLhM35").get(0):"");

            //需方公司名称
            Map buyerCompany = new HashMap();
            buyerCompany.put("componentKey", "buyerCompany");
            buyerCompany.put("componentValue", formData.containsKey("textField_mkkr6eru")?UtilMap.getString(formData, "textField_mkkr6eru"):"");

            //需方公司地址
            Map buyerAddress = new HashMap();
            buyerAddress.put("componentKey", "buyerAddress");
            buyerAddress.put("componentValue",formData.containsKey("textareaField_ml3g7xro")?UtilMap.getString(formData, "textareaField_ml3g7xro"):"");

            //需方法定代表人
            Map buyerBoss = new HashMap();
            buyerBoss.put("componentKey", "buyerBoss");
            buyerBoss.put("componentValue",formData.containsKey("textField_mp5c1fl4")?UtilMap.getString(formData, "textField_mp5c1fl4"):"");

            //需方签约代表人
            Map buyerSignatory = new HashMap();
            buyerSignatory.put("componentKey", "buyerSignatory");
            buyerSignatory.put("componentValue",formData.containsKey("textField_ml0iaa3i")?UtilMap.getString(formData, "textField_ml0iaa3i"):"");

            //电话传真
            Map buyerContact = new HashMap();
            buyerContact.put("componentKey", "buyerContact");
            buyerContact.put("componentValue",formData.containsKey("textField_ml0iaa3k")?UtilMap.getString(formData, "textField_ml0iaa3k"):"");

            //需方开户行
            Map buyerBank = new HashMap();
            buyerBank.put("componentKey", "buyerBank");
            buyerBank.put("componentValue",formData.containsKey("textfield_QTa8eERa")?UtilMap.getString(formData, "textfield_QTa8eERa"):"");

            //需方银行账号
            Map buyerAccount = new HashMap();
            buyerAccount.put("componentKey", "buyerAccount");
            buyerAccount.put("componentValue",formData.containsKey("textField_mjl28mb4")?UtilMap.getString(formData, "textField_mjl28mb4"):"");

            //税号
            Map buyerTax = new HashMap();
            buyerTax.put("componentKey", "buyerTax");
            buyerTax.put("componentValue",formData.containsKey("textfield_N5RrGSke")?UtilMap.getString(formData, "textfield_N5RrGSke"):"");

            // 产品明细
            List<Map> productTable = UtilMap.getList(formData, "tableField_mkdlflkr");
            List<Map> productDetail = new ArrayList<>();
            productDetail.add(getRowMap(false));
            for (int i = 0; i < productTable.size(); i++) {
                String productName = productTable.get(i).containsKey("textField_mq505rze")?UtilMap.getString(productTable.get(i), "textField_mq505rze"):"";//产品名称
                String productModel = productTable.get(i).containsKey("textField_mp5c1fkt")?UtilMap.getString(productTable.get(i), "textField_mp5c1fkt"):"";//规格型号
                String productUnit = productTable.get(i).containsKey("textField_mp5c1fku")?UtilMap.getString(productTable.get(i), "textField_mp5c1fku"):"";//产品单位
                String productNum = productTable.get(i).containsKey("numberField_mkdlflkt")?UtilMap.getString(productTable.get(i), "numberField_mkdlflkt"):"";//数量
                double productPrice = productTable.get(i).containsKey("numberField_mkdlflku")?UtilMap.getDouble(productTable.get(i), "numberField_mkdlflku"):0;//单价
                double productSum = productTable.get(i).containsKey("numberField_mkdlflkv")?UtilMap.getDouble(productTable.get(i), "numberField_mkdlflkv"):0;//金额小计
                String note = productTable.get(i).containsKey("textField_mkdlflkw")?UtilMap.getString(productTable.get(i), "textField_mkdlflkw"):"";//备注
                if (i == 0){
                    productDetail.add(getRowMap(false,productName,productModel,productUnit,productNum,productPrice,productSum,note));
                }else{
                    productDetail.add(getRowMap(true,productName,productModel,productUnit,productNum,productPrice,productSum,note));
                }
            }
            if (!productTable.isEmpty()) {
                productDetail.add(getRowMap(true, "金额合计", "大写金额(人民币)：",UtilMap.getString(formData, "textField_mpandaox"), "", "", "小写(RMB):", UtilMap.getDouble(formData, "numberfield_WAUnrcAf")));
            }
            Map productDetailMap = new HashMap();
            productDetailMap.put("componentKey", "productDetail");
            productDetailMap.put("componentValue", JSONObject.toJSONString(productDetail));

            components.add(companyTitle);
            components.add(companyEng);
            components.add(supplier);
            components.add(productAddress);
            components.add(buyer);
            components.add(contractNo);
            components.add(signDate);
            components.add(signAddress);
            components.add(companyName);
            components.add(supplySignatory);
            components.add(buyerCompany);
            components.add(buyerAddress);
            components.add(buyerSignatory);
            components.add(buyerBoss);
            components.add(buyerContact);
            components.add(buyerBank);
            components.add(buyerAccount);
            components.add(buyerTax);
            components.add(productDetailMap);

            reqBodyObj.put("docTemplateId", ht_docTemplateId);
            reqBodyObj.put("fileName", fileName+".pdf");
            reqBodyObj.put("components", components);
        }catch (Exception e){
            e.printStackTrace();
        }
    }


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

    /***
     * e签宝post请求
     */
    public  Map eqbPost(String postUrl,JSONObject reqBodyObj) {
        // 完整的请求地址
        String postAllUrl = host+postUrl;
        try {
            // 请求Body体数据
            String reqBodyData = reqBodyObj.toString();
            // 对请求Body体内的数据计算ContentMD5
            String contentMD5 = doContentMD5(reqBodyData);
            System.out.println("请求body数据:"+reqBodyData);
            System.out.println("body的md5值："+ contentMD5);

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

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

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

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

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

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

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

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

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

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

    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(org.apache.commons.codec.binary.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;
    }



}
