package com.malk.huagao.service.impl; import com.alibaba.fastjson.JSONObject; import com.malk.huagao.service.EqbService; import com.malk.huagao.utils.HTTPHelper; import com.malk.server.aliwork.YDConf; import com.malk.server.aliwork.YDParam; import com.malk.server.common.McR; import com.malk.service.aliwork.YDClient; import com.malk.service.dingtalk.DDClient; import com.malk.utils.UtilHttp; import com.malk.utils.UtilMap; import org.apache.commons.codec.binary.Base64; import org.slf4j.MDC; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.io.FileOutputStream; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URL; import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.text.MessageFormat; import java.text.SimpleDateFormat; import java.util.*; @Service public class EqbServiceImpl implements EqbService { @Autowired private YDConf ydConf; @Autowired private YDClient ydClient; @Autowired private DDClient ddClient; // 应用ID final static String appId = "5112033166"; // 应用密钥(AppSecret) final static String appKey = "c0641a1f648a68a7014be5a490f0159a"; // e签宝接口调用域名(正式环境) final static String host = "https://openapi.esign.cn"; //正式环境模板id 经销商模板 final static String jxs_templateId = "6a23f76742d74b858cdc2259a5d5c32f"; //正式环境模板id 其他客户模板 final static String qtkh_templateId = "8b7fef2257bc4093ada330dbf7c874c5"; //正式环境模板id 采购订单模板 final static String cgdd_templateId = "a0827f8946994ebfbed7f44e6b8a6ed8"; @Value(value = "${eqb.downloadFilePath}") private String downloadFilePath; @Value(value = "${server.host}") private String serverHost; @Value(value = "${eqb.signatoryPsnId}") private String signatoryPsnId; @Value(value = "${dingtalk.atUserId}") private String atUserId; @Async @Override public void autoAgree(String signFlowId,String processInstanceId) { MDC.put("MDC_KEY_PID","1003"); //1、签署后文件回写宜搭 Map fileInfo = downloadSignedFile(signFlowId); String fileId = UtilMap.getString(fileInfo, "fileId"); String fileName = UtilMap.getString(fileInfo, "fileName"); String downloadUrl = serverHost + "/huagao/eqb/files/" + fileId + ".pdf?option=download"; String previewUrl = serverHost + "/huagao/eqb/files/" + fileId + ".pdf?option=preview"; //更新宜搭实例签署后文件 Map formData = new HashMap(); Map file = new HashMap(); file.put("downloadUrl",downloadUrl); file.put("name",fileName); file.put("previewUrl",previewUrl); file.put("url",downloadUrl); file.put("ext","pdf"); formData.put("attachmentField_mj8dt3g2",Arrays.asList(file)); ydClient.operateData(YDParam.builder() .updateFormDataJson(JSONObject.toJSONString(formData)) .formInstanceId(processInstanceId) .build(), YDConf.FORM_OPERATION.update); //2、自动同意宜搭审批节点 String activityId = "node_ockpz6phx73";//审批节点id【e签宝签署(系统节点,禁止删除!)】 long taskId = 0; String userId = "";//审批人id //获取审批记录 List result = (List) ydClient.queryData(YDParam.builder() .processInstanceId(processInstanceId) .build(), YDConf.FORM_QUERY.retrieve_approval_record).getResult(); for (Map approveInfo : result) { if (activityId.equals(UtilMap.getString(approveInfo, "activityId"))){ //获取taskId taskId = UtilMap.getLong(approveInfo, "taskId"); userId = UtilMap.getString(approveInfo, "operatorUserId"); break; } } //审批 Map body = new HashMap(); body.put("outResult","AGREE");//AGREE:同意 DISAGREE:拒绝。 body.put("appType",ydConf.getAppType()); body.put("systemToken",ydConf.getSystemToken()); body.put("remark","e签宝签署完成,自动通过");//审批意见 body.put("processInstanceId",processInstanceId);//审批实例id body.put("userId",userId);//用户userid body.put("taskId",taskId);//任务id UtilHttp.doPost("https://api.dingtalk.com/v1.0/yida/tasks/execute", ddClient.initTokenHeader(), null,body); } @Async @Override public McR sign(Map map) { MDC.put("MDC_KEY_PID","1003"); //1、查询宜搭实例详情 String formInstId = UtilMap.getString(map, "formInstId"); Map formData = ydClient.queryData(YDParam.builder() .formInstanceId(formInstId) .build(), YDConf.FORM_QUERY.retrieve_id).getFormData(); String type = UtilMap.getString(formData, "selectField_mj89qndi");//用印文件类型 String fileName = UtilMap.getString(formData, "textField_meqr38kq");//用印文件名称 String signType = UtilMap.getString(formData, "radioField_mk0s5sf9");//签章类型 JSONObject reqBodyObj = new JSONObject(); List components = new ArrayList<>(); switch (type){ case "销售合同-经销商": getJxsObj(formData, components, reqBodyObj, fileName); break; case "销售合同-其他客户": getQtkhObj(formData,components,reqBodyObj,fileName); break; case "采购订单": getCgddObj(formData,components,reqBodyObj,fileName); break; default:break; } //2、填充模板生成文件 Map result = eqbPost("/v3/files/create-by-doc-template", reqBodyObj); String fileId = UtilMap.getString(result,"fileId"); //文档转换pdf需时间 try { Thread.sleep(3000); } catch (InterruptedException e) { throw new RuntimeException(e); } //3、基于文件发起签署 JSONObject reqBodyObj2 = new JSONObject(); //设置待签署文件信息 Map docs = new HashMap(); docs.put("fileId", fileId); reqBodyObj2.put("docs", Arrays.asList(docs)); //签署流程配置项 Map signFlowConfig = new HashMap(); signFlowConfig.put("signFlowTitle",fileName); signFlowConfig.put("autoFinish",true); signFlowConfig.put("notifyUrl",serverHost + "/huagao/eqb/callback");//回调地址 reqBodyObj2.put("signFlowConfig",signFlowConfig); //签署方信息 //我方 Map signer = new HashMap(); signer.put("signerType",1);//签署方类型,0 - 个人,1 - 企业/机构,2 - 法定代表人,3 - 经办人 Map orgSignerInfo = new HashMap(); orgSignerInfo.put("orgId","a5ec8fb7d8cc4276bd486824df0ec640");//华高机构id //企业/机构经办人信息 Map transactorInfo = new HashMap(); transactorInfo.put("psnId",signatoryPsnId);//陈伟东 orgSignerInfo.put("transactorInfo",transactorInfo); signer.put("orgSignerInfo",orgSignerInfo); /*Map psnSignerInfo = new HashMap(); psnSignerInfo.put("psnId",signatoryPsnId);//陈伟东 signer.put("psnSignerInfo",psnSignerInfo);*/ Map signField = new HashMap(); signField.put("fileId",fileId); signField.put("customBizNum",formInstId); Map normalSignFieldConfig = new HashMap(); normalSignFieldConfig.put("freeMode",true); /*normalSignFieldConfig.put("autoSign",true); normalSignFieldConfig.put("signFieldStyle",1); Map signFieldPosition = new HashMap(); signFieldPosition.put("positionPage",1); normalSignFieldConfig.put("signFieldPosition",signFieldPosition);*/ signField.put("normalSignFieldConfig",normalSignFieldConfig); signer.put("signFields",Arrays.asList(signField)); reqBodyObj2.put("signers",Arrays.asList(signer)); //他方 String jbr = ""; String jbrdh = ""; String orgName = ""; if ("双方签章".equals(signType)){ switch (type){ case "销售合同-经销商": jbr = UtilMap.getString(formData, "textField_mk0s5sfa");//需方经办人 jbrdh = UtilMap.getString(formData, "textField_mf50cbqw");//需方经办人电话 orgName = UtilMap.getString(formData, "textField_mjaukh2p");//需方名称 break; case "销售合同-其他客户": jbr = UtilMap.getString(formData, "textField_mk0s5sfh");//需方经办人 jbrdh = UtilMap.getString(formData, "textField_mk0s5sfg");//需方经办人电话 orgName = UtilMap.getString(formData, "textField_mjaukh2p");//需方名称 break; case "采购订单": jbr = UtilMap.getString(formData, "textField_mj8dt3g8");//供方经办人 jbrdh = UtilMap.getString(formData, "textField_mj8dt3g9");//供方经办人电话 orgName = UtilMap.getString(formData, "textField_mj8dt3g7");//供方名称 break; default:break; } Map signer2 = new HashMap(); signer2.put("signerType",1);//签署方类型,0 - 个人,1 - 企业/机构,2 - 法定代表人,3 - 经办人 Map orgSignerInfo2 = new HashMap(); orgSignerInfo2.put("orgName",orgName);//对方机构名称 //企业/机构经办人信息 Map transactorInfo2 = new HashMap(); transactorInfo2.put("psnAccount",jbrdh);//经办人账号标识,手机号或邮箱,必须配合psnName(经办人姓名)传入 Map psnInfo = new HashMap(); psnInfo.put("psnName",jbr);//经办人姓名 transactorInfo2.put("psnInfo",psnInfo); orgSignerInfo2.put("transactorInfo",transactorInfo2); signer2.put("orgSignerInfo",orgSignerInfo2); Map signField2 = new HashMap(); signField2.put("fileId",fileId); signField2.put("customBizNum",formInstId); Map normalSignFieldConfig2 = new HashMap(); normalSignFieldConfig2.put("freeMode",true); signField2.put("normalSignFieldConfig",normalSignFieldConfig2); signer2.put("signFields",Arrays.asList(signField2)); reqBodyObj2.put("signers",Arrays.asList(signer,signer2)); } Map result2 = eqbPost("/v3/sign-flow/create-by-file", reqBodyObj2); String signFlowId = UtilMap.getString(result2, "signFlowId"); //4、回写签署地址 JSONObject reqBodyObj3 = new JSONObject(); Map operator = new HashMap(); operator.put("psnId", signatoryPsnId); reqBodyObj3.put("operator", operator); Map result3 = eqbPost("/v3/sign-flow/" + signFlowId + "/sign-url", reqBodyObj3); String shortUrl = UtilMap.getString(result3, "shortUrl"); ydClient.operateData(YDParam.builder() .formInstanceId(formInstId) .content("签署地址:"+shortUrl) .userId("yida_pub_account") .atUserId(atUserId)//陈伟东 .build(), YDConf.FORM_OPERATION.remarks); if ("双方签章".equals(signType)){ System.out.println("获取对方签署地址"); JSONObject reqBodyObj4 = new JSONObject(); Map operator2 = new HashMap(); operator2.put("psnAccount", jbrdh); reqBodyObj4.put("operator", operator2); reqBodyObj4.put("needLogin", true); Map result4 = eqbPost("/v3/sign-flow/" + signFlowId + "/sign-url", reqBodyObj4); String shortUrl2 = UtilMap.getString(result4, "shortUrl"); ydClient.operateData(YDParam.builder() .formInstanceId(formInstId) .content("对方签署地址:"+shortUrl2) .userId("yida_pub_account") .build(), YDConf.FORM_OPERATION.remarks); } return McR.success(); } private void getJxsObj(Map formData,List components,JSONObject reqBodyObj,String fileName){ String dgdbh = UtilMap.getString(formData, "textField_mjas1rkm");//订购单编号 String xf = UtilMap.getString(formData, "textField_mjaukh2p");//需方 String xfdz = UtilMap.getString(formData, "textareaField_mf50cbqt");//需方地址 String xfdh = UtilMap.getString(formData, "textField_mf50cbqw");//需方电话 String xfjbr = UtilMap.getString(formData, "textField_mj8dt3fj");//需方经办人 String gfdh = UtilMap.getString(formData, "textField_mjau7ffr");//供方电话 String gfjbr = UtilMap.getString(formData, "textField_mjauqjr9");//供方经办人 long ddrq = UtilMap.getLong(formData, "dateField_mj8dt3fa");//订单日期 String ghkjxybh = UtilMap.getString(formData, "textField_mjas1rkn");//供货框架协议编号 Double jehj = UtilMap.getDouble(formData, "numberField_me1335n7");//金额合计 String jehjdx = UtilMap.getString(formData, "textField_mf50cbvj");//金额合计大写 String fktj = UtilMap.getString(formData, "radioField_mf50cbu7");//付款条件 String xfnsrsbh = UtilMap.getString(formData, "textField_mf50cbuj");//需方纳税人识别号 String xfkhyh = UtilMap.getString(formData, "textField_mf50cbup");//需方开户银行 String xfzh = UtilMap.getString(formData, "textField_mf50cbuk");//需方账号 List xshtmxList = UtilMap.getList(formData, "tableField_mf50cbre");//销售合同明细 List jhdzList = UtilMap.getList(formData, "tableField_mj8dt3fk");//交货地址 //订购单编号 Map jxsComponent = new HashMap(); jxsComponent.put("componentKey", "dgdbh"); jxsComponent.put("componentValue", dgdbh); //需方 Map jxsComponent2 = new HashMap(); jxsComponent2.put("componentKey", "xf"); jxsComponent2.put("componentValue", xf); //需方地址 Map jxsComponent3 = new HashMap(); jxsComponent3.put("componentKey", "xfdz"); jxsComponent3.put("componentValue", xfdz); //需方电话 Map jxsComponent4 = new HashMap(); jxsComponent4.put("componentKey", "xfdh"); jxsComponent4.put("componentValue", xfdh); //需方经办人 Map jxsComponent5 = new HashMap(); jxsComponent5.put("componentKey", "xfjbr"); jxsComponent5.put("componentValue", xfjbr); //供方电话 Map jxsComponent6 = new HashMap(); jxsComponent6.put("componentKey", "gfdh"); jxsComponent6.put("componentValue", gfdh); //供方经办人 Map jxsComponent7 = new HashMap(); jxsComponent7.put("componentKey", "gfjbr"); jxsComponent7.put("componentValue", gfjbr); //订单日期 Map jxsComponent8 = new HashMap(); jxsComponent8.put("componentKey", "ddrq"); jxsComponent8.put("componentValue", ddrq); //供货框架协议编号 Map jxsComponent9 = new HashMap(); jxsComponent9.put("componentKey", "ghkjxybh"); jxsComponent9.put("componentValue", ghkjxybh); //金额合计 Map jxsComponent10 = new HashMap(); jxsComponent10.put("componentKey", "jehj"); jxsComponent10.put("componentValue", jehj); //金额合计大写 Map jxsComponent11 = new HashMap(); jxsComponent11.put("componentKey", "jehjdx"); jxsComponent11.put("componentValue", jehjdx); //付款条件 Map jxsComponent12 = new HashMap(); if ("款到发货".equals(fktj)){ jxsComponent12.put("componentKey", "xkhh"); jxsComponent12.put("componentValue", true); }else { jxsComponent12.put("componentKey", "qt"); jxsComponent12.put("componentValue", true); } //需方纳税人识别号 Map jxsComponent13 = new HashMap(); jxsComponent13.put("componentKey", "xfnsrsbh"); jxsComponent13.put("componentValue", xfnsrsbh); //需方开户银行 Map jxsComponent14 = new HashMap(); jxsComponent14.put("componentKey", "xfkhyh"); jxsComponent14.put("componentValue", xfkhyh); //需方账号 Map jxsComponent15 = new HashMap(); jxsComponent15.put("componentKey", "xfzh"); jxsComponent15.put("componentValue", xfzh); //销售合同明细 List xshtmx = new ArrayList<>(); xshtmx.add(getRowMap(false)); for (int i = 0; i < xshtmxList.size(); i++) { String cpmc = UtilMap.getString(xshtmxList.get(i), "textField_mf50cbrf");//产品名称 String cpxh = UtilMap.getString(xshtmxList.get(i), "textField_mf50cbrg");//产品型号 String dw = UtilMap.getString(xshtmxList.get(i), "textField_mf50cbrh");//单位 String xssl = UtilMap.getString(xshtmxList.get(i), "numberField_mfbx1pr4");//销售数量 double lsdj = UtilMap.getDouble(xshtmxList.get(i), "numberField_mf50cbri");//零售单价 double pfyhdj = UtilMap.getDouble(xshtmxList.get(i), "numberField_mf50cbrj");//批发优惠单价 String zbq = UtilMap.getString(xshtmxList.get(i), "textField_mjas1rkx");//质保期 if (i == 0){ xshtmx.add(getRowMap(false,i+1,cpmc,cpxh,dw,lsdj,pfyhdj,zbq)); }else { xshtmx.add(getRowMap(true,i+1,cpmc,cpxh,dw,lsdj,pfyhdj,zbq)); } } Map jxsComponent16 = new HashMap(); jxsComponent16.put("componentKey", "xshtmx"); jxsComponent16.put("componentValue", JSONObject.toJSONString(xshtmx)); //交货地址 List jhdz = new ArrayList<>(); jhdz.add(getRowMap(false)); for (int i = 0; i < jhdzList.size(); i++) { String shdz = UtilMap.getString(jhdzList.get(i), "textField_mj8dt3fl");//收货地址 String shr = UtilMap.getString(jhdzList.get(i), "textField_mj8dt3fm");//收货人 String shrlxdh = UtilMap.getString(jhdzList.get(i), "textField_mj8dt3fn");//收货人联系电话 if (i == 0){ jhdz.add(getRowMap(false,i+1,shdz,shr,shrlxdh)); }else { jhdz.add(getRowMap(true,i+1,shdz,shr,shrlxdh)); } } Map jxsComponent17 = new HashMap(); jxsComponent17.put("componentKey", "jhdz"); jxsComponent17.put("componentValue", JSONObject.toJSONString(jhdz)); Map jxsComponent19 = new HashMap(); jxsComponent19.put("componentKey", "xf2"); jxsComponent19.put("componentValue", xf); Map jxsComponent20 = new HashMap(); jxsComponent20.put("componentKey", "xfdz2"); jxsComponent20.put("componentValue", xfdz); components.add(jxsComponent); components.add(jxsComponent2); components.add(jxsComponent3); components.add(jxsComponent4); components.add(jxsComponent5); components.add(jxsComponent6); components.add(jxsComponent7); components.add(jxsComponent8); components.add(jxsComponent9); components.add(jxsComponent10); components.add(jxsComponent11); components.add(jxsComponent12); components.add(jxsComponent13); components.add(jxsComponent14); components.add(jxsComponent15); components.add(jxsComponent16); components.add(jxsComponent17); components.add(jxsComponent19); components.add(jxsComponent20); if (!"款到发货".equals(fktj)){ Map jxsComponent18 = new HashMap(); jxsComponent18.put("componentKey", "qtnr"); jxsComponent18.put("componentValue", fktj); components.add(jxsComponent18); } // 构建请求Body体 reqBodyObj.put("docTemplateId", jxs_templateId); reqBodyObj.put("fileName", fileName+".pdf"); reqBodyObj.put("components", components); } private void getQtkhObj(Map formData, List components, JSONObject reqBodyObj, String fileName){ String htbh = UtilMap.getString(formData, "textField_mjb71q95");//合同编号 String jf = UtilMap.getString(formData, "textField_mjaukh2p");//甲方 double xsze = UtilMap.getDouble(formData, "numberField_mjb71qac");//销售总额 String fkfs = UtilMap.getString(formData, "textField_mjb886fw");//付款方式 String jfnsrsbh = UtilMap.getString(formData, "textField_mjb71q9w");//甲方纳税人识别号 String spyx = UtilMap.getString(formData, "textField_mjb71q9y");//收票邮箱 String jfdb = UtilMap.getString(formData, "textField_mjb886fx");//甲方代表 String yfdb = UtilMap.getString(formData, "textField_mj8dt3fj");//乙方代表 List xshtmxList = UtilMap.getList(formData, "tableField_mjb71qab");//销售合同明细 //订购单编号 Map jxsComponent = new HashMap(); jxsComponent.put("componentKey", "htbh"); jxsComponent.put("componentValue", htbh); //甲方 Map jxsComponent2 = new HashMap(); jxsComponent2.put("componentKey", "jf"); jxsComponent2.put("componentValue", jf); //销售总额 Map jxsComponent3 = new HashMap(); jxsComponent3.put("componentKey", "xsze"); jxsComponent3.put("componentValue", xsze); //付款方式 Map jxsComponent4 = new HashMap(); jxsComponent4.put("componentKey", "fkfs"); jxsComponent4.put("componentValue", fkfs); //甲方纳税人识别号 Map jxsComponent5 = new HashMap(); jxsComponent5.put("componentKey", "jfnsrsbh"); jxsComponent5.put("componentValue", jfnsrsbh); //收票邮箱 Map jxsComponent6 = new HashMap(); jxsComponent6.put("componentKey", "spyx"); jxsComponent6.put("componentValue", spyx); //甲方代表 Map jxsComponent7 = new HashMap(); jxsComponent7.put("componentKey", "jfdb"); jxsComponent7.put("componentValue", jfdb); //乙方代表 Map jxsComponent8 = new HashMap(); jxsComponent8.put("componentKey", "yfdb"); jxsComponent8.put("componentValue", yfdb); //销售合同明细 List xshtmx = new ArrayList<>(); xshtmx.add(getRowMap(false)); for (int i = 0; i < xshtmxList.size(); i++) { String cpmc = UtilMap.getString(xshtmxList.get(i), "textField_mjb71qa4");//产品名称 String cpxh = UtilMap.getString(xshtmxList.get(i), "textField_mjb71qa5");//产品型号 String dw = UtilMap.getString(xshtmxList.get(i), "textField_mjb71qa6");//单位 String xssl = UtilMap.getString(xshtmxList.get(i), "numberField_mjb71qa7");//销售数量 double hsdj = UtilMap.getDouble(xshtmxList.get(i), "numberField_mjb71qa8");//含税单价 int zbq = UtilMap.getInt(xshtmxList.get(i), "numberField_mjb71qaw");//质保期 String smzs = UtilMap.getString(xshtmxList.get(i), "textField_mjb71qam");//扫描张数 double jshj = UtilMap.getDouble(xshtmxList.get(i), "numberField_mjb71qan");//价税合计 double zke = UtilMap.getDouble(xshtmxList.get(i), "numberField_mjb71qao");//折扣额 String bz = UtilMap.getString(xshtmxList.get(i), "textField_mjb71qaq");//备注 if (i == 0){ xshtmx.add(getRowMap(false,cpmc,cpxh,dw,xssl,hsdj,zbq+"年",smzs,jshj,zke,bz)); }else { xshtmx.add(getRowMap(true,cpmc,cpxh,dw,xssl,hsdj,zbq+"年",smzs,jshj,zke,bz)); } } Map jxsComponent9 = new HashMap(); jxsComponent9.put("componentKey", "xshtmx"); jxsComponent9.put("componentValue", JSONObject.toJSONString(xshtmx)); //甲方 Map jxsComponent10 = new HashMap(); jxsComponent10.put("componentKey", "jf2"); jxsComponent10.put("componentValue", jf); //甲方 Map jxsComponent11 = new HashMap(); jxsComponent11.put("componentKey", "jf3"); jxsComponent11.put("componentValue", jf); components.add(jxsComponent); components.add(jxsComponent2); components.add(jxsComponent3); components.add(jxsComponent4); components.add(jxsComponent5); components.add(jxsComponent6); components.add(jxsComponent7); components.add(jxsComponent8); components.add(jxsComponent9); components.add(jxsComponent10); components.add(jxsComponent11); // 构建请求Body体 reqBodyObj.put("docTemplateId", qtkh_templateId); reqBodyObj.put("fileName", fileName+".pdf"); reqBodyObj.put("components", components); } private void getCgddObj(Map formData,List components,JSONObject reqBodyObj,String fileName){ String cgddbh = UtilMap.getString(formData, "textField_mj9msq4v");//采购订单编号 long date = UtilMap.getLong(formData, "dateField_mj8dt3g6");//签订日期 String yf = UtilMap.getString(formData, "textField_mj8dt3g7");//乙方 String yfdz = UtilMap.getString(formData, "textField_mj8dt3gt");//乙方地址 String yflxr = UtilMap.getString(formData, "textField_mj8dt3g8");//乙方联系人 String yfdh = UtilMap.getString(formData, "textField_mj8dt3g9");//乙方电话 String nsrsbh = UtilMap.getString(formData, "textField_mj8dt3gs");//乙方纳税人识别号 String khyh = UtilMap.getString(formData, "textField_mj8dt3gq");//乙方开户银行 String zh = UtilMap.getString(formData, "textField_mj8dt3gr");//乙方账号 String zlyq = UtilMap.getString(formData, "textField_mj8dt3gn");//质量要求 String jsfs = UtilMap.getString(formData, "textField_mj8dt3go");//结算方式及付款期限 String bz = UtilMap.getString(formData, "textareaField_mj9msq4w");//备注 List cgmx = UtilMap.getList(formData, "tableField_mizdd3qf");//采购明细 double zjyf = UtilMap.getDouble(formData, "numberField_mj9msq4x");//总计应付 String jflxr = UtilMap.getString(formData, "textField_mjb2kuhf");//甲方联系人 String jflxdh = UtilMap.getString(formData, "textField_mjb2kuhh");//甲方联系电话 //订单编号 Map component = new HashMap(); component.put("componentKey", "ddbh"); component.put("componentValue", cgddbh); //签订日期 Map component2 = new HashMap(); component2.put("componentKey", "qdrq"); component2.put("componentValue", date); //乙方 Map component3 = new HashMap(); component3.put("componentKey", "yf"); component3.put("componentValue", yf); //乙方联系人 Map component4 = new HashMap(); component4.put("componentKey", "yflxr"); component4.put("componentValue", yflxr); //乙方联系电话 Map component5 = new HashMap(); component5.put("componentKey", "yflxdh"); component5.put("componentValue", yfdh); //备注 Map component6 = new HashMap(); component6.put("componentKey", "bz"); component6.put("componentValue", bz); //销售合同明细 List cghtmx = new ArrayList<>(); cghtmx.add(getRowMap(false)); for (int i = 0; i < cgmx.size(); i++) { String wlbm = UtilMap.getString(cgmx.get(i), "textField_mizdd3qg");//物料编码 String wlmc = UtilMap.getString(cgmx.get(i), "textField_mizdd3qh");//物料名称 String ggxh = UtilMap.getString(cgmx.get(i), "textField_mizdd3qi");//规格型号 String cgdw = UtilMap.getString(cgmx.get(i), "textField_mizdd3qj");//采购单位 double cgsl = UtilMap.getDouble(cgmx.get(i), "numberField_mizdd3ql");//采购数量 double hsdj = UtilMap.getDouble(cgmx.get(i), "numberField_mizdd3qs");//含税单价 double jshj = UtilMap.getDouble(cgmx.get(i), "numberField_mizdd3qx");//价税合计 long jhrq = UtilMap.getLong(cgmx.get(i), "dateField_mizdd3qp");//交货日期 //时间戳转化为年月日 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); String jhrqStr = sdf.format(new Date(jhrq)); String mxbz = UtilMap.getString(cgmx.get(i), "textField_mizdd3r0");//备注 if (i == 0){ cghtmx.add(getRowMap(false,i+1,wlbm,wlmc,null,ggxh,cgsl,cgdw,hsdj,jshj,jhrqStr,mxbz)); }else { cghtmx.add(getRowMap(true,i+1,wlbm,wlmc,null,ggxh,cgsl,cgdw,hsdj,jshj,jhrqStr,mxbz)); } } Map component7 = new HashMap(); component7.put("componentKey", "cgmx"); component7.put("componentValue", JSONObject.toJSONString(cghtmx)); //总计应付 Map component8 = new HashMap(); component8.put("componentKey", "zjyf"); component8.put("componentValue", zjyf); //质量要求 Map component9 = new HashMap(); component9.put("componentKey", "zlyq"); component9.put("componentValue", zlyq); //结算方式及付款期限 Map component10 = new HashMap(); component10.put("componentKey", "jsfs"); component10.put("componentValue", jsfs); //乙方 Map component11 = new HashMap(); component11.put("componentKey", "yf2"); component11.put("componentValue", yf); //乙方开户银行 Map component12 = new HashMap(); component12.put("componentKey", "yfkhyh"); component12.put("componentValue", khyh); //乙方账号 Map component13 = new HashMap(); component13.put("componentKey", "yfzh"); component13.put("componentValue", zh); //乙方纳税人识别号 Map component14 = new HashMap(); component14.put("componentKey", "yfnsrsbh"); component14.put("componentValue", nsrsbh); //乙方地址 Map component15 = new HashMap(); component15.put("componentKey", "yfdz"); component15.put("componentValue", yfdz); //甲方联系人 Map component16 = new HashMap(); component16.put("componentKey", "jflxr"); component16.put("componentValue", jflxr); //甲方联系电话 Map component17 = new HashMap(); component17.put("componentKey", "jflxdh"); component17.put("componentValue", jflxdh); components.add(component); components.add(component2); components.add(component3); components.add(component4); components.add(component5); components.add(component6); components.add(component7); components.add(component8); components.add(component9); components.add(component10); components.add(component11); components.add(component12); components.add(component13); components.add(component14); components.add(component15); components.add(component16); components.add(component17); // 构建请求Body体 reqBodyObj.put("docTemplateId", cgdd_templateId); reqBodyObj.put("fileName", fileName+".pdf"); reqBodyObj.put("components", components); } /*** * e签宝post请求 */ public static Map eqbPost(String postUrl,JSONObject reqBodyObj) { // 完整的请求地址 String postAllUrl = host + postUrl; try { // 请求Body体数据 String reqBodyData = reqBodyObj.toString(); // 对请求Body体内的数据计算ContentMD5 String contentMD5 = doContentMD5(reqBodyData); System.out.println("请求body数据:"+reqBodyData); System.out.println("body的md5值:"+ contentMD5); // 构建待签名字符串 String method = "POST"; String accept = "*/*"; String contentType = "application/json"; String url = postUrl; String date = ""; String headers = ""; StringBuffer sb = new StringBuffer(); sb.append(method).append("\n").append(accept).append("\n").append(contentMD5).append("\n") .append(contentType).append("\n").append(date).append("\n"); if ("".equals(headers)) { sb.append(headers).append(url); } else { sb.append(headers).append("\n").append(url); } // 构建参与请求签名计算的明文 String plaintext = sb.toString(); // 计算请求签名值 String reqSignature = doSignatureBase64(plaintext, appKey); System.out.println("计算请求签名值:"+reqSignature); // 获取时间戳(精确到毫秒) long timeStamp = timeStamp(); // 构建请求头 LinkedHashMap header = new LinkedHashMap(); header.put("X-Tsign-Open-App-Id", appId); header.put("X-Tsign-Open-Auth-Mode", "Signature"); header.put("X-Tsign-Open-Ca-Timestamp", String.valueOf(timeStamp)); header.put("Accept", accept); header.put("Content-Type", contentType); header.put("X-Tsign-Open-Ca-Signature", reqSignature); header.put("Content-MD5", contentMD5); // 发送POST请求 String result = HTTPHelper.sendPOST(postAllUrl, reqBodyData, header, "UTF-8"); System.out.println("请求返回信息: " + result); Map resultObj =(Map) JSONObject.parse(result); Map data = UtilMap.getMap(resultObj, "data"); return data; } catch (Exception e) { e.printStackTrace(); String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage()); System.out.println(msg); throw new RuntimeException(e); } } private Map downloadSignedFile(String signFlowId){ // 计算签名拼接的url String postUrl = "/v3/sign-flow/" + signFlowId + "/file-download-url"; Map result = eqbPost(postUrl, new JSONObject()); List files =(List) UtilMap.getList(result, "files"); String downloadUrl = UtilMap.getString(files.get(0), "downloadUrl"); String fileName = UtilMap.getString(files.get(0), "fileName"); UUID fileId = UUID.randomUUID(); String downloadPath = downloadFilePath + fileId + ".pdf"; downloadFile(downloadUrl,downloadPath); Map result2 = new HashMap(); result2.put("downloadPath",downloadPath); result2.put("fileName",fileName); result2.put("fileId",fileId); return result2; } //文件下载到本地 private void downloadFile(String downloadUri,String downloadPath){ try { URL url = new URL(downloadUri); HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); int responseCode = httpConn.getResponseCode(); // 检查HTTP响应代码是否为200 if (responseCode == HttpURLConnection.HTTP_OK) { InputStream inputStream = httpConn.getInputStream(); FileOutputStream outputStream = new FileOutputStream(downloadPath); byte[] buffer = new byte[4096]; int bytesRead = -1; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } outputStream.close(); inputStream.close(); } else { System.out.println("无法下载文件。HTTP响应代码: " + responseCode); } httpConn.disconnect(); }catch (Exception e){ throw new RuntimeException(e); } } /*** * * @param str 待计算的消息 * @return MD5计算后摘要值的Base64编码(ContentMD5) * @throws Exception 加密过程中的异常信息 */ public static String doContentMD5(String str) throws Exception { byte[] md5Bytes = null; MessageDigest md5 = null; String contentMD5 = null; try { md5 = MessageDigest.getInstance("MD5"); // 计算md5函数 md5.update(str.getBytes("UTF-8")); // 获取文件MD5的二进制数组(128位) md5Bytes = md5.digest(); // 把MD5摘要后的二进制数组md5Bytes使用Base64进行编码(而不是对32位的16进制字符串进行编码) contentMD5 = new String(Base64.encodeBase64(md5Bytes), "UTF-8"); } catch (NoSuchAlgorithmException e) { String msg = MessageFormat.format("不支持此算法: {0}", e.getMessage()); Exception ex = new Exception(msg); ex.initCause(e); throw ex; } catch (UnsupportedEncodingException e) { String msg = MessageFormat.format("不支持的字符编码: {0}", e.getMessage()); Exception ex = new Exception(msg); ex.initCause(e); throw ex; } return contentMD5; } /*** * 计算请求签名值 * * @param message 待计算的消息 * @param secret 密钥 * @return HmacSHA256计算后摘要值的Base64编码 * @throws Exception 加密过程中的异常信息 */ public static String doSignatureBase64(String message, String secret) throws Exception { String algorithm = "HmacSHA256"; Mac hmacSha256; String digestBase64 = null; try { hmacSha256 = Mac.getInstance(algorithm); byte[] keyBytes = secret.getBytes("UTF-8"); byte[] messageBytes = message.getBytes("UTF-8"); hmacSha256.init(new SecretKeySpec(keyBytes, 0, keyBytes.length, algorithm)); // 使用HmacSHA256对二进制数据消息Bytes计算摘要 byte[] digestBytes = hmacSha256.doFinal(messageBytes); // 把摘要后的结果digestBytes使用Base64进行编码 digestBase64 = new String(Base64.encodeBase64(digestBytes), "UTF-8"); } catch (NoSuchAlgorithmException e) { String msg = MessageFormat.format("不支持此算法: {0}", e.getMessage()); Exception ex = new Exception(msg); ex.initCause(e); throw ex; } catch (UnsupportedEncodingException e) { String msg = MessageFormat.format("不支持的字符编码: {0}", e.getMessage()); Exception ex = new Exception(msg); ex.initCause(e); throw ex; } catch (InvalidKeyException e) { String msg = MessageFormat.format("无效的密钥规范: {0}", e.getMessage()); Exception ex = new Exception(msg); ex.initCause(e); throw ex; } return digestBase64; } /*** * 获取时间戳(毫秒级) * * @return 毫秒级时间戳,如 1578446909000 */ public static long timeStamp() { long timeStamp = System.currentTimeMillis(); return timeStamp; } private static Map getRowMap(boolean insertRow,Object... columnValues) { Map row = new HashMap(); for (int i = 0; i < columnValues.length; i++) { row.put("column" + (i + 1), columnValues[i]); } Map result = new HashMap(); result.put("row",row); result.put("insertRow",insertRow); return result; } }