Browse Source

恒益隆对接e签宝

hxx 1 month ago
parent
commit
6446b2df05

+ 84 - 0
mjava-hengyilong/pom.xml

@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>com.malk.hengyilong</groupId>
+    <artifactId>mjava-hengyilong</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <name>mjava-hengyilong</name>
+    <description>mjava-hengyilong</description>
+    <properties>
+        <java.version>1.8</java.version>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <spring-boot.version>2.6.13</spring-boot.version>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.malk</groupId>
+            <artifactId>base</artifactId>
+            <version>1.3</version>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-dependencies</artifactId>
+                <version>${spring-boot.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <build>
+        <finalName>hengyilong</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.8.1</version>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                    <encoding>UTF-8</encoding>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>${spring-boot.version}</version>
+                <configuration>
+                    <mainClass>com.malk.hengyilong.HengyilongApplication</mainClass>
+<!--                    <skip>true</skip>-->
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>repackage</id>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 17 - 0
mjava-hengyilong/src/main/java/com/malk/hengyilong/HengyilongApplication.java

@@ -0,0 +1,17 @@
+package com.malk.hengyilong;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication(scanBasePackages = {"com.malk"})
+public class HengyilongApplication {
+
+    public static void main(String[] args) {
+        try {
+            SpringApplication.run(HengyilongApplication.class,args);
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+}

+ 109 - 0
mjava-hengyilong/src/main/java/com/malk/hengyilong/controller/HylController.java

@@ -0,0 +1,109 @@
+package com.malk.hengyilong.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.malk.server.common.McR;
+import com.malk.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.web.bind.annotation.*;
+import com.malk.hengyilong.service.ClientHylService;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 功能:
+ * 作者:hanxue
+ * 日期:2026/2/2 10:14
+ */
+@RequestMapping
+@RestController
+@Slf4j
+public class HylController {
+
+    @Autowired
+    private ClientHylService clientService;
+
+    //    获取客户档案信息
+    @GetMapping("/getClient")
+    public McR getClient(@RequestBody  Map param){
+        return clientService.getClient(param);
+    }
+    //同步宜搭客户档案链接
+    @PostMapping("/syncClient")
+    public McR syncClient(@RequestBody Map map){
+        return clientService.syncClient(map);
+    }
+
+
+
+    // 使用ConcurrentHashMap保证线程安全
+    private final ConcurrentMap<String, Long> eventList = new ConcurrentHashMap<>();
+    // 记录最后一次清理时间
+    private volatile long lastCleanTime = System.currentTimeMillis();
+    // 清理间隔时间(毫秒)
+    private static final long CLEAN_INTERVAL = 60_000;
+//    @PostMapping("/callback")
+//    public McR callback(@RequestBody Map map){
+//        System.out.println(map);
+//
+//        log.info("e签宝回调: {}", JSON.toJSONString(map));
+//
+//        //签署回调通知:SIGN_MISSON_COMPLETE   事件订阅-签署流程完成:SIGN_FLOW_FINISH
+//        String action = UtilMap.getString(map, "action");
+//        String signFlowId = UtilMap.getString(map, "signFlowId");//e签宝签署流程id
+//
+//        String info = action + "-" + signFlowId;
+//
+//        // 定期清理过期记录
+//        cleanExpiredEvents();
+//
+//        if (isCallbackProcessed(info)){
+//            log.info("info:{},重复回调,不做处理",info);
+//        }else {
+//            eventList.put(info, System.currentTimeMillis());
+//            //签署回调结束
+//            if ("SIGN_MISSON_COMPLETE".equals(action)) {
+//                int signResult = UtilMap.getInt(map, "signResult");//2 - 签署完成,4 - 拒签
+//                if (2 == signResult) {
+//                    String processInstanceId = UtilMap.getString(map, "customBizNum");//宜搭审批实例id
+//                    //自动同意审批节点
+//                    eqbService.autoAgree(signFlowId,processInstanceId);
+//                }
+//            }
+//        }
+//
+//        return McR.success();
+//    }
+
+    /**
+     * 检查并清理过期事件
+     */
+    private void cleanExpiredEvents() {
+        long currentTime = System.currentTimeMillis();
+        // 只在达到清理间隔时执行清理
+        if (currentTime - lastCleanTime > CLEAN_INTERVAL) {
+            synchronized (this) {
+                // 双重检查,避免重复清理
+                if (currentTime - lastCleanTime > CLEAN_INTERVAL) {
+                    long expirationTime = currentTime - TimeUnit.MINUTES.toMillis(1);
+                    eventList.entrySet().removeIf(entry -> entry.getValue() < expirationTime);
+                    lastCleanTime = currentTime;
+                }
+            }
+        }
+    }
+
+    /**
+     * 检查该回调事件在一分钟内是否处理过
+     */
+    private boolean isCallbackProcessed(String detail) {
+        return eventList.containsKey(detail);
+    }
+
+
+
+}

+ 109 - 0
mjava-hengyilong/src/main/java/com/malk/hengyilong/controller/HylEqbController.java

@@ -0,0 +1,109 @@
+package com.malk.hengyilong.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.malk.hengyilong.service.EqbHylService;
+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.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 功能:
+ * 作者:hanxue
+ * 日期:2026/4/24 18:00
+ */
+@RequestMapping
+@RestController
+@Slf4j
+public class HylEqbController {
+    @Autowired
+    private YDClient ydClient;
+    @Autowired
+    private EqbHylService eqbService;
+    @PostMapping("/quotationToEqb")
+    public McR syncClient(@RequestBody Map map){
+        return eqbService.quotationToEqb(map);
+    }
+
+    // 使用ConcurrentHashMap保证线程安全
+    private final ConcurrentMap<String, Long> eventList = new ConcurrentHashMap<>();
+    // 记录最后一次清理时间
+    private volatile long lastCleanTime = System.currentTimeMillis();
+    // 清理间隔时间(毫秒)
+    private static final long CLEAN_INTERVAL = 60_000;
+    @PostMapping("/callback")
+    public McR callback(@RequestBody Map map) {
+        log.info("e签宝回调: {}", JSON.toJSONString(map));
+        //签署回调通知:SIGN_MISSON_COMPLETE   签署流程完成:SIGN_FLOW_FINISH
+        String action = UtilMap.getString(map, "action");
+        String signFlowId = UtilMap.getString(map, "signFlowId");//e签宝签署流程id
+
+        String info = action + "-" + signFlowId;
+
+        // 定期清理过期记录
+        cleanExpiredEvents();
+
+        if (isCallbackProcessed(info)){
+            log.info("info:{},重复回调,不做处理",info);
+        }else {
+            eventList.put(info, System.currentTimeMillis());
+            //签署回调结束
+            if ("SIGN_MISSON_COMPLETE".equals(action)) {
+                int signResult = UtilMap.getInt(map, "signResult");//2 - 签署完成,4 - 拒签
+                String processInstanceId = UtilMap.getString(map, "customBizNum");//宜搭审批实例id
+                if (2 == signResult) {
+//                   更新宜搭报价单状态
+                    ydClient.operateData(YDParam.builder()
+                            .formInstanceId(processInstanceId)
+                            .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mpcayrsc","已签署")))
+                            .build(), YDConf.FORM_OPERATION.update);
+                }else {
+                    ydClient.operateData(YDParam.builder()
+                            .formInstanceId(processInstanceId)
+                            .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mpcayrsc","拒签")))
+                            .build(), YDConf.FORM_OPERATION.update);
+                }
+            }
+        }
+        return McR.success();
+    }
+
+    /**
+     * 检查并清理过期事件
+     */
+    private void cleanExpiredEvents() {
+        long currentTime = System.currentTimeMillis();
+        // 只在达到清理间隔时执行清理
+        if (currentTime - lastCleanTime > CLEAN_INTERVAL) {
+            synchronized (this) {
+                // 双重检查,避免重复清理
+                if (currentTime - lastCleanTime > CLEAN_INTERVAL) {
+                    long expirationTime = currentTime - TimeUnit.MINUTES.toMillis(1);
+                    eventList.entrySet().removeIf(entry -> entry.getValue() < expirationTime);
+                    lastCleanTime = currentTime;
+                }
+            }
+        }
+    }
+
+    /**
+     * 检查该回调事件在一分钟内是否处理过
+     */
+    private boolean isCallbackProcessed(String detail) {
+        return eventList.containsKey(detail);
+    }
+
+}

+ 17 - 0
mjava-hengyilong/src/main/java/com/malk/hengyilong/service/ClientHylService.java

@@ -0,0 +1,17 @@
+package com.malk.hengyilong.service;
+
+import com.malk.server.common.McR;
+
+import java.util.Map;
+
+/**
+ * Created by malk on 2017/6/12.
+ */
+public interface ClientHylService {
+    McR getClient(Map param);
+
+    McR syncClient(Map map);
+    //查询所有
+    
+
+}

+ 9 - 0
mjava-hengyilong/src/main/java/com/malk/hengyilong/service/EqbHylService.java

@@ -0,0 +1,9 @@
+package com.malk.hengyilong.service;
+
+import com.malk.server.common.McR;
+
+import java.util.Map;
+
+public interface EqbHylService {
+    McR quotationToEqb(Map map);
+}

+ 84 - 0
mjava-hengyilong/src/main/java/com/malk/hengyilong/service/impl/ClientHylServiceImpl.java

@@ -0,0 +1,84 @@
+package com.malk.hengyilong.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.malk.hengyilong.service.ClientHylService;
+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.server.dingtalk.DDR_New;
+import com.malk.service.aliwork.YDClient;
+import com.malk.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 功能:
+ * 作者:hanxue
+ * 日期:2026/2/2 10:48
+ */
+
+@Service
+@Slf4j
+public class ClientHylServiceImpl implements ClientHylService {
+    @Autowired
+    private YDClient ydClient;
+    @Override
+    public McR getClient(Map param) {
+        DDR_New ddrNew;
+        int pageNumber = 1;
+        int pageSize = 100;
+        JSONArray clientList = new JSONArray();
+        do {
+            ddrNew = ydClient.queryData(YDParam.builder()
+                    .formUuid("FORM-GMC66781QZP16UF1NPSLG6C8ZC9G38R5V6IJM1")
+                    .searchFieldJson(JSONObject.toJSONString(Arrays.asList(
+                            new YDSearch("selectField_mkm0qu7p", "锁定", "selectField_mkm0qu7p", YDSearch.Type.TEXT_FIELD, YDSearch.Operator.EQ),
+                            new YDSearch("employeeField_mkm0ce8w", param.get("userId"), "employeeField_mkm0ce8w",YDSearch.Type.EMPLOYEE_FIELD, YDSearch.Operator.CONTAINS)
+                    )))
+                    .pageNumber(pageNumber)
+                    .pageSize(pageSize)
+                    .build(), YDConf.FORM_QUERY.retrieve_list_all);
+            if (ddrNew != null && ddrNew.getData() != null) {
+                JSONArray currentPageData = (JSONArray) ddrNew.getData();
+                clientList.addAll(currentPageData);
+                System.out.println("已处理第 " + pageNumber + " 页数据,当前页记录数: " + currentPageData.size());
+                if (currentPageData.size() < pageSize) {
+                    break;
+                }
+            }
+            pageNumber++;  // 准备查询下一页
+        } while (ddrNew != null && ddrNew.getTotalCount() > (pageNumber - 1) * pageSize);
+        List clientNameList = new ArrayList();
+        for(int i=0;i<clientList.size();i++) {
+            Map client = (Map) clientList.get(i);
+            Map formData = (Map) client.get("formData");
+           String clientName = UtilMap.getString(formData,"textfield_uB2fZYNg");
+            clientNameList.add(clientName);
+        }
+        log.info("clientList:{}",clientNameList);
+        return McR.success(clientNameList);
+    }
+
+    @Override
+    public McR syncClient(Map map) {
+         List clientdetails = (List) ydClient.queryData(YDParam.builder()
+                .formUuid("FORM-GMC66781QZP16UF1NPSLG6C8ZC9G38R5V6IJM1")
+                .searchFieldJson(JSONObject.toJSONString(Arrays.asList(
+                        new YDSearch("textfield_uB2fZYNg", UtilMap.getString(map, "clientName"), "textfield_uB2fZYNg", YDSearch.Type.TEXT_FIELD, YDSearch.Operator.EQ)
+                )))
+                .build(), YDConf.FORM_QUERY.retrieve_list_all).getData();
+        Map clientdetail = (Map) clientdetails.get(0);
+        log.info("clientList:{}",clientdetail.get("formInstanceId"));
+        String clientLink = "https://gkwk0b.aliwork.com/APP_QX8IOI1D22HK3GC413L5/formDetail/FORM-GMC66781QZP16UF1NPSLG6C8ZC9G38R5V6IJM1?formInstId="+clientdetail.get("formInstanceId");
+        return McR.success(clientLink);
+    }
+}

+ 592 - 0
mjava-hengyilong/src/main/java/com/malk/hengyilong/service/impl/EqbHylServiceImpl.java

@@ -0,0 +1,592 @@
+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.orgId}")
+    private String orgId;
+    @Value("${eqb.psnId}")
+    private String psnId;
+    @Value("${server.host}")
+    private String serverHost;
+
+    private static String bjd_docTemplateId ="1d2f50e82f514144b72313b1dddcb552";
+
+    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);
+                    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设置签署参与方
+            Map signer = new HashMap();
+            signer.put("signerType",1);//签署方类型,0 - 个人,1 - 企业/机构,2 - 法定代表人,3 - 经办人
+            Map orgSignerInfo = new HashMap();
+            //企业/机构账号ID
+            orgSignerInfo.put("orgId",orgId);
+            //经办人信息
+            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));
+            reqBodyObjSign.put("signers",Arrays.asList(signer));
+            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",shortUrl)))
+                    .build(), YDConf.FORM_OPERATION.update);
+            return McR.success(shortUrl);
+
+//            return McR.success(fileId);
+        } catch (Exception e) {
+            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 productName = productTable.get(i).containsKey("textField_mn5wpqov")?UtilMap.getString(productTable.get(i), "textField_mn5wpqov"):"";//产品名称
+            String productModel = productTable.get(i).containsKey("textField_mogxdk7x")?UtilMap.getString(productTable.get(i), "textField_mogxdk7x"):"";//产品型号
+            String productUnit = 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"):"";//数量
+            double productPrice = productTable.get(i).containsKey("numberField_mkdl67qe")?UtilMap.getDouble(productTable.get(i), "numberField_mkdl67qe"):0;//单价
+            String note = productTable.get(i).containsKey("textField_mjb71qaq")?UtilMap.getString(productTable.get(i), "textField_mjb71qaq"):"";//备注
+            if (i == 0){
+                productDetail.add(getRowMap(false,productName,productModel,productUnit,productNum,productPrice,note));
+            }else {
+                productDetail.add(getRowMap(true,productName,productModel,productUnit,productNum,productPrice,note));
+            }
+        }
+        Map productDetailMap = new HashMap();
+        productDetailMap.put("componentKey", "productDetail");
+        productDetailMap.put("componentValue", JSONObject.toJSONString(productDetail));
+
+        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);
+        reqBodyObj.put("docTemplateId", bjd_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 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_mkdlflks")?UtilMap.getString(productTable.get(i), "textField_mkdlflks"):"";//产品名称
+                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_mjb71qaq")?UtilMap.getString(productTable.get(i), "textField_mjb71qaq"):"";//备注
+                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.getDouble(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(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;
+    }
+
+
+
+}

+ 267 - 0
mjava-hengyilong/src/main/java/com/malk/hengyilong/utils/HTTPHelper.java

@@ -0,0 +1,267 @@
+package com.malk.hengyilong.utils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map.Entry;
+
+public class HTTPHelper {
+    // slf4j日志记录器
+    private static final Logger LOG = LoggerFactory.getLogger(HTTPHelper.class);
+
+    /***
+     * 向指定URL发送GET方法的请求
+     *
+     * @param apiUrl
+     * @param data
+     * @param projectId
+     * @param signature
+     * @param encoding
+     * @return
+     * @throws Exception
+     */
+    public static String sendGet(String apiUrl, HashMap<String, Object> param,
+                                 LinkedHashMap<String, String> headers, String encoding) throws Exception {
+        // 获得响应内容
+        String http_RespContent = null;
+        HttpURLConnection httpURLConnection = null;
+        int http_StatusCode = 0;
+        String http_RespMessage = null;
+        try {
+            // 实际请求完整Url
+            StringBuffer fullUrl = new StringBuffer();
+            if (null != param) {
+                if (0 != param.size()) {
+                    StringBuffer params = new StringBuffer();
+                    for (Entry<String, Object> entry : param.entrySet()) {
+                        params.append(entry.getKey());
+                        params.append("=");
+                        params.append(entry.getValue().toString());
+                        params.append("&");
+                    }
+                    if (params.length() > 0) {
+                        params.deleteCharAt(params.lastIndexOf("&"));
+                    }
+                    fullUrl.append(apiUrl).append((params.length() > 0) ? "?" + params.toString() : "");
+                } else {
+                    fullUrl.append(apiUrl);
+                }
+            } else {
+                fullUrl.append(apiUrl);
+            }
+
+            LOG.info(">>>> 实际请求Url: " + fullUrl.toString());
+
+            // 建立连接
+            URL url = new URL(fullUrl.toString());
+            httpURLConnection = (HttpURLConnection) url.openConnection();
+            // 需要输出
+            httpURLConnection.setDoOutput(true);
+            // 需要输入
+            httpURLConnection.setDoInput(true);
+            // 不允许缓存
+            httpURLConnection.setUseCaches(false);
+            // HTTP请求方式
+            httpURLConnection.setRequestMethod("GET");
+            // 设置Headers
+            if (null != headers) {
+                for (String key : headers.keySet()) {
+                    httpURLConnection.setRequestProperty(key, headers.get(key));
+                }
+            }
+            // 连接会话
+            httpURLConnection.connect();
+            // 获得响应状态(HTTP状态码)
+            http_StatusCode = httpURLConnection.getResponseCode();
+            // 获得响应消息(HTTP状态码描述)
+            http_RespMessage = httpURLConnection.getResponseMessage();
+            // 获得响应内容
+            if (HttpURLConnection.HTTP_OK == http_StatusCode) {
+                // 返回响应结果
+                http_RespContent = getResponseContent(httpURLConnection);
+            } else {
+                // 返回非200状态时响应结果
+                http_RespContent = getErrorResponseContent(httpURLConnection);
+                String msg =
+                        MessageFormat.format("请求失败: Http状态码 = {0} , {1}", http_StatusCode, http_RespMessage);
+                LOG.info(msg);
+            }
+        } catch (UnknownHostException e) {
+            String message = MessageFormat.format("网络请求时发生异常: {0}", e.getMessage());
+            Exception ex = new Exception(message);
+            ex.initCause(e);
+            throw ex;
+        } catch (MalformedURLException e) {
+            String message = MessageFormat.format("格式错误的URL: {0}", e.getMessage());
+            Exception ex = new Exception(message);
+            ex.initCause(e);
+            throw ex;
+        } catch (IOException e) {
+            String message = MessageFormat.format("网络请求时发生异常: {0}", e.getMessage());
+            Exception ex = new Exception(message);
+            ex.initCause(e);
+            throw ex;
+        } catch (Exception e) {
+            String message = MessageFormat.format("网络请求时发生异常: {0}", e.getMessage());
+            Exception ex = new Exception(message);
+            ex.initCause(e);
+            throw ex;
+        } finally {
+            if (null != httpURLConnection) {
+                httpURLConnection.disconnect();
+            }
+        }
+        return http_RespContent;
+    }
+
+    /***
+     * 向指定URL发送POST方法的请求
+     *
+     * @param apiUrl
+     * @param data
+     * @param projectId
+     * @param signature
+     * @param encoding
+     * @return
+     * @throws Exception
+     */
+    public static String sendPOST(String apiUrl, String data, LinkedHashMap<String, String> headers,
+                                  String encoding) throws Exception {
+        // 获得响应内容
+        String http_RespContent = null;
+        HttpURLConnection httpURLConnection = null;
+        int http_StatusCode = 0;
+        String http_RespMessage = null;
+        try {
+            // 建立连接
+            URL url = new URL(apiUrl);
+            httpURLConnection = (HttpURLConnection) url.openConnection();
+            // 需要输出
+            httpURLConnection.setDoOutput(true);
+            // 需要输入
+            httpURLConnection.setDoInput(true);
+            // 不允许缓存
+            httpURLConnection.setUseCaches(false);
+            // HTTP请求方式
+            httpURLConnection.setRequestMethod("POST");
+            // 设置Headers
+            if (null != headers) {
+                for (String key : headers.keySet()) {
+                    httpURLConnection.setRequestProperty(key, headers.get(key));
+                }
+            }
+            // 连接会话
+            httpURLConnection.connect();
+            // 建立输入流,向指向的URL传入参数
+            DataOutputStream dos = new DataOutputStream(httpURLConnection.getOutputStream());
+            // 设置请求参数
+            dos.write(data.getBytes(encoding));
+            dos.flush();
+            dos.close();
+            // 获得响应状态(HTTP状态码)
+            http_StatusCode = httpURLConnection.getResponseCode();
+            // 获得响应消息(HTTP状态码描述)
+            http_RespMessage = httpURLConnection.getResponseMessage();
+            // 获得响应内容
+            if (HttpURLConnection.HTTP_OK == http_StatusCode) {
+                // 返回响应结果
+                http_RespContent = getResponseContent(httpURLConnection);
+            } else {
+                // 返回非200状态时响应结果
+                http_RespContent = getErrorResponseContent(httpURLConnection);
+                String msg =
+                        MessageFormat.format("请求失败: Http状态码 = {0} , {1}", http_StatusCode, http_RespMessage);
+                LOG.info(msg);
+            }
+        } catch (UnknownHostException e) {
+            String message = MessageFormat.format("网络请求时发生异常: {0}", e.getMessage());
+            Exception ex = new Exception(message);
+            ex.initCause(e);
+            throw ex;
+        } catch (MalformedURLException e) {
+            String message = MessageFormat.format("格式错误的URL: {0}", e.getMessage());
+            Exception ex = new Exception(message);
+            ex.initCause(e);
+            throw ex;
+        } catch (IOException e) {
+            String message = MessageFormat.format("网络请求时发生异常: {0}", e.getMessage());
+            Exception ex = new Exception(message);
+            ex.initCause(e);
+            throw ex;
+        } catch (Exception e) {
+            String message = MessageFormat.format("网络请求时发生异常: {0}", e.getMessage());
+            Exception ex = new Exception(message);
+            ex.initCause(e);
+            throw ex;
+        } finally {
+            if (null != httpURLConnection) {
+                httpURLConnection.disconnect();
+            }
+        }
+        return http_RespContent;
+    }
+
+    /***
+     * 读取HttpResponse响应内容
+     *
+     * @param httpURLConnection
+     * @return
+     * @throws UnsupportedEncodingException
+     * @throws IOException
+     */
+    private static String getResponseContent(HttpURLConnection httpURLConnection)
+            throws UnsupportedEncodingException, IOException {
+        StringBuffer contentBuffer = null;
+        BufferedReader responseReader = null;
+        try {
+            contentBuffer = new StringBuffer();
+            String readLine = null;
+            responseReader =
+                    new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(), "UTF-8"));
+            while ((readLine = responseReader.readLine()) != null) {
+                contentBuffer.append(readLine);
+            }
+        } finally {
+            if (null != responseReader) {
+                responseReader.close();
+            }
+        }
+        return contentBuffer.toString();
+    }
+
+    /***
+     * 读取HttpResponse响应内容
+     *
+     * @param httpURLConnection
+     * @return
+     * @throws UnsupportedEncodingException
+     * @throws IOException
+     */
+    private static String getErrorResponseContent(HttpURLConnection httpURLConnection)
+            throws UnsupportedEncodingException, IOException {
+        StringBuffer contentBuffer = null;
+        BufferedReader responseReader = null;
+        try {
+            contentBuffer = new StringBuffer();
+            String readLine = null;
+            responseReader =
+                    new BufferedReader(new InputStreamReader(httpURLConnection.getErrorStream(), "UTF-8"));
+            while ((readLine = responseReader.readLine()) != null) {
+                contentBuffer.append(readLine);
+            }
+        } finally {
+            if (null != responseReader) {
+                responseReader.close();
+            }
+        }
+        return contentBuffer.toString();
+    }
+}

+ 49 - 0
mjava-hengyilong/src/main/resources/application-dev.yml

@@ -0,0 +1,49 @@
+server:
+  port: 9002
+  servlet:
+    context-path: /hengyilong
+  host: https://poc.cloudpure.cn/
+
+enable:
+  scheduling: false
+logging:
+  config: classpath:logback-spring.xml
+  path: /home/server/hengyilong/log/
+  level:
+    com.malk.*: debug
+
+
+mybatis-plus:
+  configuration:
+    #开启驼峰命名自动映射
+    map-underscore-to-camel-case: false
+    #开启日志打印
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+  type-aliases-package: com.malk.hengyilong.entity
+  #扫描mapper文件
+  mapper-locations: classpath:mapper/*.xml
+
+# dingtalk
+dingtalk:
+  agentId:
+  appKey: dinglrt7qaqjmlnwaaul
+  appSecret: FBWNzNC8i9srucJmqo5iOo61icmbzA_dDquuIzVXYa2hSlP8aGIrhYPeQXemqy3Z
+  corpId:
+  aesKey:
+  token:
+  operator:
+
+aliwork:
+  appType: APP_QX8IOI1D22HK3GC413L5
+  systemToken: AXD66JB143P1C5Q8K93RR75ZEXSK2379ZYHJMP09
+
+eqb:
+  host: https://smlopenapi.esign.cn
+  appKey: ae304291c5702141ea7c98bcdaae6a17
+  appId: 7439110455
+  orgId: 04dd6dbad3d8456b9e551fc329c516d7
+  psnId: c086503ade9a4a3aba83f69c07b14178
+  bjd_docTemplateId: ee7bdf1404154c0686ed38a7cf65a7ff
+  ht_docTemplateId: 0064564bea704fc587a249680064b98c
+
+

+ 46 - 0
mjava-hengyilong/src/main/resources/application-prod.yml

@@ -0,0 +1,46 @@
+server:
+  port: 9031
+  servlet:
+    context-path: /hengyilong
+  host: https://poc.cloudpure.cn/
+
+enable:
+  scheduling: false
+logging:
+  config: classpath:logback-spring.xml
+  path: /home/server/hengyilong/log/
+  level:
+    com.malk.*: debug
+
+mybatis-plus:
+  configuration:
+    #开启驼峰命名自动映射
+    map-underscore-to-camel-case: false
+    #开启日志打印
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+  type-aliases-package: com.malk.hengyilong.entity
+  #扫描mapper文件
+  mapper-locations: classpath:mapper/*.xml
+
+# dingtalk
+dingtalk:
+  agentId:
+  appKey: dinglrt7qaqjmlnwaaul
+  appSecret: FBWNzNC8i9srucJmqo5iOo61icmbzA_dDquuIzVXYa2hSlP8aGIrhYPeQXemqy3Z
+  corpId:
+  aesKey:
+  token:
+  operator:
+
+aliwork:
+  appType: APP_QX8IOI1D22HK3GC413L5
+  systemToken: AXD66JB143P1C5Q8K93RR75ZEXSK2379ZYHJMP09
+
+eqb:
+  host: https://openapi.esign.cn
+  appKey: 7e464621b3aa4a0e39a6557009b38214
+  appId: 5112061694
+  orgId: fed0042d62a848de9052de45b31b83ea
+  psnId: b15ea57b95bb4b6883b5cc759e1c342d # 合同章负责人-覃李勇
+  bjd_docTemplateId: 1d2f50e82f514144b72313b1dddcb552
+  ht_docTemplateId: 0064564bea704fc587a249680064b98c

+ 15 - 0
mjava-hengyilong/src/main/resources/application.yml

@@ -0,0 +1,15 @@
+spring:
+  profiles:
+    active: prod
+  servlet:
+    multipart:
+      max-file-size: 100MB
+      max-request-size: 100MB
+  http:
+    enabled: false
+
+#  configuration:
+#    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+  global-config:
+    db-config:
+      id-type: auto

+ 61 - 0
mjava-hengyilong/src/main/resources/logback-spring.xml

@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration debug="false" scan="false" scanPeriod="60 seconds">
+    <springProperty scope="context" name="LOG_HOME" source="logging.path" defaultValue="/home/server/log/"/>
+    <property name="FileNamePattern" value="${LOG_HOME}%d{yyyyMM}/%d{dd}"/>
+
+    <!-- 定义控制台输出 -->
+    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
+        <layout class="ch.qos.logback.classic.PatternLayout">
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} - [%thread] - %-5level - %logger{50} - %msg%n</pattern>
+        </layout>
+    </appender>
+
+    <appender name="appLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 指定日志文件的名称 -->
+        <!--<file>${FileNamePattern}/info.log</file>-->
+
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>${FileNamePattern}/info-%i.log</fileNamePattern>
+            <MaxHistory>30</MaxHistory>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <MaxFileSize>30MB</MaxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+
+        <layout class="ch.qos.logback.classic.PatternLayout">
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [ %thread ] - [ %-5level ] [ %logger{50} : %line ] - %msg%n</pattern>
+        </layout>
+    </appender>
+
+    <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
+        <discriminator>
+            <Key>processid</Key>
+            <DefaultValue>sys</DefaultValue>
+        </discriminator>
+        <sift>
+            <appender name="FILE-${processid}"
+                      class="ch.qos.logback.core.rolling.RollingFileAppender">
+                <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                    <FileNamePattern>
+                        ${FileNamePattern}/${processid}.log
+                    </FileNamePattern>
+                </rollingPolicy>
+                <layout class="ch.qos.logback.classic.PatternLayout">
+                    <Pattern>
+                        %d{yyyyMMdd:HH:mm:ss.SSS} [%thread] %-5level %msg%n
+                    </Pattern>
+                </layout>
+            </appender>
+        </sift>
+    </appender>
+
+
+    <!-- 日志输出级别 -->
+    <logger name="org.springframework" level="debug"  additivity="false"/>
+    <logger name="com.malk.connecter" level="debug"/>
+    <root level="INFO">
+        <appender-ref ref="stdout"/>
+        <appender-ref ref="appLogAppender"/>
+        <appender-ref ref="SIFT"/>
+    </root>
+</configuration>

+ 38 - 0
mjava-hengyilong/src/test/java/com/malk/hengyilong/mjavahengyilong/MjavaHengyilongApplicationTests.java

@@ -0,0 +1,38 @@
+package com.malk.hengyilong.mjavahengyilong;
+
+import com.malk.hengyilong.service.ClientHylService;
+import com.malk.hengyilong.service.EqbHylService;
+import com.malk.hengyilong.service.impl.ClientHylServiceImpl;
+import com.malk.server.common.McR;
+import com.malk.utils.UtilMap;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@SpringBootTest
+class MjavaHengyilongApplicationTests {
+
+    @Autowired
+    private ClientHylService clientHylService;
+    @Autowired
+    private EqbHylService eqbHylService;
+    @Test
+    void contextLoads() {
+    }
+
+    @Test
+    void getClient(){
+        Map map = new HashMap();
+        map.put("userId","3044156512693449078");
+        McR mcR = clientHylService.getClient(map);
+    }
+
+    @Test
+    void quotationToEqb(){
+//        McR mcR = eqbHylService.quotationToEqb(UtilMap.map("formInstance, type","65b19c02-6b53-455f-937e-73e9135c561d, contract"));
+    }
+
+}

File diff suppressed because it is too large
+ 1170 - 0
mjava-hengyilong/src/test/java/com/malk/hengyilong/mjavahengyilong/ToEqbTest.java