Browse Source

博洋家纺

wzy 2 weeks ago
parent
commit
6d8e5e7149

+ 10 - 0
mjava-boyang/pom.xml

@@ -39,6 +39,16 @@
             <artifactId>base</artifactId>
             <version>1.1-SNAPSHOT</version>
         </dependency>
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>okhttp</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>aliyun-java-core</artifactId>
+            <version>0.2.10-beta</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>

+ 87 - 3
mjava-boyang/src/main/java/com/malk/boyang/controller/BoyangController.java

@@ -1,18 +1,102 @@
 package com.malk.boyang.controller;
 
+import com.alibaba.fastjson.JSON;
 import com.malk.boyang.service.BoyangService;
 import com.malk.server.common.McR;
+import com.malk.utils.UtilMap;
+import com.malk.utils.UtilServlet;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
 @RestController
-@RequestMapping
+@RequestMapping()
 public class BoyangController {
 
     @Autowired
     private BoyangService boyangService;
 
+    @PostMapping("/sign")
+    public McR sign(@RequestBody Map body) {
+        return boyangService.eSignSubmit(body);
+    }
+
+    @GetMapping("/getOrganization")
+    public McR getOrganization(String name) {
+        return boyangService.getOrganization(name);
+    }
+
+    // 使用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 Map callback(@RequestBody Map body) {
+//        Map data = UtilServlet.getParamMap(request);
+        log.info("data, {}", JSON.toJSONString(body));
+
+        //签署流程开始:SIGN_FLOW_START;签署节点完成:SIGN_SIGNER_SIGNED;签署流程完成:SIGN_FLOW_FINISH
+        String callBackDesc = UtilMap.getString(body, "callBackDesc");
+        int callBackEnum = UtilMap.getInt(body, "callBackEnum");
+
+        Map callBackProcessVO = UtilMap.getMap(body, "callBackProcessVO");
+        String signFlowId = UtilMap.getString(callBackProcessVO, "processId");//e签宝签署流程id
+        String processInstanceId = UtilMap.getString(callBackProcessVO, "businessNo");//钉钉审批实例id
+
+        String info = callBackDesc + "-" + callBackEnum + signFlowId;
+
+        // 定期清理过期记录
+        cleanExpiredEvents();
+
+        if (isCallbackProcessed(info)){
+            log.info("info:{},重复回调,不做处理",info);
+        }else {
+            eventList.put(info, System.currentTimeMillis());
+            //签署完成回写审批单
+            if ("SIGN_FLOW_FINISH".equals(callBackDesc)) {
+                boyangService.signed(processInstanceId,signFlowId);
+            }
+        }
+
+        Map map = new HashMap();
+        map.put("code", 0);
+        map.put("msg","success");
+        return map;
+    }
 
+    /**
+     * 检查并清理过期事件
+     */
+    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);
+    }
 }

+ 8 - 0
mjava-boyang/src/main/java/com/malk/boyang/service/BoyangService.java

@@ -2,6 +2,14 @@ package com.malk.boyang.service;
 
 import com.malk.server.common.McR;
 
+import java.util.Map;
+
 public interface BoyangService {
+    //发起e签宝签署
+    McR eSignSubmit(Map map);
+
+    //e签宝签署完成回写签署文件
+    void signed(String processInstanceId,String signFlowId);
 
+    McR getOrganization(String name);
 }

+ 596 - 6
mjava-boyang/src/main/java/com/malk/boyang/service/impl/BoyangServiceImpl.java

@@ -1,27 +1,617 @@
 package com.malk.boyang.service.impl;
 
 import cn.hutool.core.date.DateUtil;
-import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.malk.boyang.service.BoyangService;
-import com.malk.server.aliwork.YDConf;
-import com.malk.server.aliwork.YDParam;
+import com.malk.boyang.utils.HTTPHelper;
 import com.malk.server.common.McR;
+import com.malk.server.dingtalk.DDConf;
 import com.malk.server.dingtalk.DDR_New;
-import com.malk.service.aliwork.YDClient;
 import com.malk.service.dingtalk.DDClient;
+import com.malk.service.dingtalk.DDClient_Storage;
+import com.malk.service.dingtalk.DDClient_Workflow;
 import com.malk.utils.UtilHttp;
 import com.malk.utils.UtilMap;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringEscapeUtils;
-import org.apache.logging.log4j.util.Strings;
+import okhttp3.*;
+import okio.BufferedSink;
+import okio.Okio;
+import okio.Sink;
+import org.apache.commons.codec.binary.Hex;
+import org.apache.commons.codec.digest.HmacAlgorithms;
+import org.apache.commons.codec.digest.HmacUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.text.MessageFormat;
 import java.util.*;
 
 @Slf4j
 @Service
 public class BoyangServiceImpl implements BoyangService {
+    @Autowired
+    private DDClient ddClient;
+
+    @Autowired
+    private DDClient_Workflow ddClient_workflow;
+
+    @Value("${dingtalk.downloadPath}")
+    private String downloadPath;
+
+    @Value("${dingtalk.operatorUnionId}")
+    private String operatorUnionId;
+
+    @Value("${dingtalk.operator}")
+    private String operator;
+
+    @Value("${dingtalk.spaceId}")
+    private String spaceId;
+
+    @Value("${dingtalk.parentDentryUuid}")
+    private String parentDentryUuid;
+
+    //测试环境
+    final static String projectId = "1000004";// 应用ID
+    final static String secret = "96Uh7CR83NkN3TA6";// 应用密钥
+    final static String businessTypeCode = "889726e889ab84fea3514748d6df565c";// 钉钉对接测试业务模板
+    final static String host = "http://122.227.225.202:9011/";// 接口调用域名
+    final static String intranet_host = "http://11.0.11.62/";// 接口调用域名(内网)
+
+    @Override
+    public McR eSignSubmit(Map map) {
+        String processInstanceId = UtilMap.getString(map, "processInstanceId");
+
+        Map result = ddClient_workflow.getProcessInstanceId(ddClient.getAccessToken(), processInstanceId);
+
+        List<Map> formComponentValues = UtilMap.getList(result, "formComponentValues");
+
+        List<Map<String,String>> fileList = new ArrayList<>();
+
+        String subject = "";
+        String remark = "";
+        String url = "https://aflow.dingtalk.com/dingtalk/web/query/pchomepage.htm?from=oflow&op=true&corpid=ding76a1e955807327f7f5bf40eda33b7ba0#/plainapproval?procInstId="+processInstanceId;
+        List<String> sealTypeCodeList = new ArrayList<>();
+
+
+        for (Map formComponentValue : formComponentValues) {
+            String id = UtilMap.getString(formComponentValue, "id");
+
+            switch (id){
+                case "TextField-K2AD4O5B"://文件名称
+                    subject = UtilMap.getString(formComponentValue, "value");
+
+                    //将subject里的"/"替换为","
+                    subject = subject.replaceAll("/",",");
+                    break;
+                case "DDSelectField_RIHDKAA2UK00"://文件类型
+                    String fileType = UtilMap.getString(formComponentValue, "value");
+                    break;
+                case "DDSelectField_1G1RJG8MDU9S0"://合同/协议类文件
+                    String htxywj = UtilMap.getString(formComponentValue, "value");
+                    break;
+                case "DDSelectField_28JHJ0TGPN6S"://是否需要骑缝章
+                    String isQifeng = UtilMap.getString(formComponentValue, "value");
+                    break;
+                case "TextField_1P4TDG767SRK0"://文件份数
+                    String fileQty = UtilMap.getString(formComponentValue, "value");
+                    break;
+                case "DDMultiSelectField_1L3KU3TLX6PS0"://印章所属公司
+                    String companyStr = UtilMap.getString(formComponentValue, "value");
+                    List<Map> companyList = (List<Map>) JSONObject.parse(companyStr);
+                    break;
+                case "DDMultiSelectField_1FW3TFDTJ6V40"://印章类型
+                    String yzlxStr = UtilMap.getString(formComponentValue, "value");
+                    List<String> yzlxList = (List<String>) JSONObject.parse(yzlxStr);
+
+                    for (String yzlx : yzlxList) {
+                           switch (yzlx){
+                               case "公章":sealTypeCodeList.add("PUBLIC");break;
+                               case "合同章":sealTypeCodeList.add("CONTRACT");break;
+                               case "财务章":sealTypeCodeList.add("FINANCE");break;
+                               case "其他":sealTypeCodeList.add("COMMON");break;
+                               case "人事专用章":sealTypeCodeList.add("PERSONNEL");break;
+                               case "法人章":sealTypeCodeList.add("LEGAL-PERSON-SEAL");break;
+                               default:break;
+                           }
+                    }
+                    break;
+                case "DDSelectField_1JL8JW2HM5PC0"://用印方式
+                    String yyfs = UtilMap.getString(formComponentValue, "value");
+
+                    if (!"电子签章".equals(yyfs)){
+//                        return McR.success("非电子签章无需处理");
+                    }
+                    break;
+                case "TextField_17O0AUUY9L6K0"://签署备注
+                    remark = UtilMap.getString(formComponentValue, "value");
+                    break;
+                case "DDAttachment_1V002NDXYVKW0"://附件
+                    String attachmentListStr = UtilMap.getString(formComponentValue, "value");
+                    List<Map> attachmentList = (List<Map>) JSONObject.parse(attachmentListStr);
+                    for (Map attachment : attachmentList) {
+                        String fileId = UtilMap.getString(attachment, "fileId");
+                        String fileName = UtilMap.getString(attachment, "fileName");
+
+                        //下载钉盘文件
+                        String filePath = downloadPath + fileName;
+                        downloadDdFile(processInstanceId,fileId,filePath);
+
+                        Map fileMap = new HashMap();
+                        fileMap.put("filePath", filePath);
+                        fileMap.put("fileName", fileName);
+
+                        fileList.add(fileMap);
+                    }
+                    break;
+            }
+        }
+
+        // 创建主Map
+        Map<String, Object> requestMap = new HashMap<>();
+
+        // 1. 基本字段
+        requestMap.put("subject", subject);
+        requestMap.put("businessNo", processInstanceId);
+        requestMap.put("businessTypeCode", businessTypeCode);
+        requestMap.put("remark", remark);
+        requestMap.put("redirectUrl", url);
+
+        // 2. manualConfig 嵌套对象
+        Map<String, Object> manualConfig = new HashMap<>();
+        manualConfig.put("startMode", 1);
+        manualConfig.put("finishMode", 0);
+
+        // signingAreaPageConfig 子对象
+        Map<String, Object> signingAreaPageConfig = new HashMap<>();
+        signingAreaPageConfig.put("showStartButton", 1);
+        manualConfig.put("signingAreaPageConfig", signingAreaPageConfig);
+
+        requestMap.put("manualConfig", manualConfig);
+
+        // 3. initiatorInfo 嵌套对象
+        Map<String, Object> initiatorInfo = new HashMap<>();
+        initiatorInfo.put("userCode", "wozy");
+        initiatorInfo.put("customAccountNo", "");
+        initiatorInfo.put("departmentCode", "");
+        initiatorInfo.put("customDepartmentNo", "");
+        initiatorInfo.put("organizationCode", "b60a9c18b8cc4ecc80e30f36b4267a68");
+        initiatorInfo.put("customOrgNo", "");
+
+        requestMap.put("initiatorInfo", initiatorInfo);
+
+        // 4. signFiles 列表
+        List<Map<String, Object>> signFiles = new ArrayList<>();
+
+        for (int i = 0; i < fileList.size(); i++) {
+            String fileKey = uploadAndConvertEqbFile(fileList.get(i).get("filePath"), fileList.get(i).get("fileName"));
+
+            Map<String, Object> file = new HashMap<>();
+            file.put("fileKey", fileKey);
+            file.put("fileOrder", i + 1);
+
+            signFiles.add(file);
+        }
+
+        requestMap.put("signFiles", signFiles);
+
+        // 5. signerInfos 列表
+        List<Map<String, Object>> signerInfos = new ArrayList<>();
+
+        Map<String, Object> signer = new HashMap<>();
+        signer.put("userType", "1");
+        signer.put("userCode", "wozy");
+        signer.put("organizationCode", "b60a9c18b8cc4ecc80e30f36b4267a68");
+        signer.put("signNode", 1);
+        signer.put("signMode", "0");
+        signer.put("signOrder", 1);
+//        signer.put("sealTypeCode", String.join(",",sealTypeCodeList));
+
+        signerInfos.add(signer);
+        requestMap.put("signerInfos", signerInfos);
+
+        // 打印结果(可选)
+        System.out.println(requestMap);
+
+        //使用文件发起签署(一步发起签署)
+        Map data = (Map) eqbPost(host + "/esign-signs/v1/signFlow/createAndStart", requestMap);
+
+        //签署区设置地址回写评论
+        Map manualConfig1 = UtilMap.getMap(data, "manualConfig");
+
+        Map signingAreaPageInfos = UtilMap.getMap(manualConfig1, "signingAreaPageInfos");
+
+        String signingAreaPageUrl = UtilMap.getString(signingAreaPageInfos, "signingAreaPageUrl");
+
+        String newSigningAreaPageUrl = signingAreaPageUrl.replace(intranet_host,host);
+
+        comment(processInstanceId,"344749020127590108","签署区设置地址:"+newSigningAreaPageUrl,null);
+
+        return McR.success();
+    }
+
+    @Override
+    public void signed(String processInstanceId,String signFlowId) {
+        try {
+            // 获取签署流程进度详情
+            Map data = (Map) eqbGet(host + "/esign-signs/v1/signFlow/signDetail?signFlowId=" + signFlowId);
+            List<Map> signFiles = UtilMap.getList(data, "signFiles");
+
+            for (Map signFile : signFiles) {
+                String fileKey = UtilMap.getString(signFile, "fileKey");
+                String signDownloadOuterUrl = UtilMap.getString(signFile, "signDownloadOuterUrl");
+                String fileName = getEqbFileName(fileKey);
+
+                int suffixIndex = fileName.lastIndexOf(".");
+
+                String signedFileName = fileName.substring(0, suffixIndex) + "(已签署)" + fileName.substring(suffixIndex);
+
+                //todo 1、评论签署后附件下载链接
+//                    comment(processInstanceId,userId,"接口测试 "+ fileName + "已签署,签署文件下载地址:" + signDownloadOuterUrl,null);
+
+
+
+                //todo 2、评论签署后附件
+                //todo 签署后文件下载到本地
+                downloadFile(signDownloadOuterUrl,downloadPath + signedFileName);
+                //todo 签署后文件上传到钉盘
+                Map dentry = uploadDdFile(spaceId, parentDentryUuid, downloadPath + signedFileName, operatorUnionId);
+                //todo 审批单添加评论
+                comment(processInstanceId,operator,"接口测试 "+ fileName + "已签署",Arrays.asList(dentry));
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
+            System.out.println(msg);
+        }
+    }
+
+    @Override
+    public McR getOrganization(String name) {
+        Map body = new HashMap();
+        body.put("name",name);
+        List<Map> data = (List<Map>) eqbPost(host + "manage/v1/innerOrganizations/detail",body);
+
+        List<Map> options = new ArrayList<>();
+
+        for (Map datum : data) {
+            String organizationName = UtilMap.getString(datum, "name");
+            String organizationCode = UtilMap.getString(datum, "organizationCode");
+
+            Map option = new HashMap();
+            option.put("label",organizationName);
+            option.put("value",organizationCode);
+
+            options.add(option);
+        }
+
+        return McR.success(options);
+    }
+
+    //下载钉钉OA审批单附件
+    private void downloadDdFile(String processInstanceId,String fileId,String downloadPath){
+        try {
+            Map body = new HashMap();
+            body.put("processInstanceId",processInstanceId);
+            body.put("fileId",fileId);
+
+            DDR_New ddrNew = (DDR_New) UtilHttp.doPost("https://api.dingtalk.com/v1.0/workflow/processInstances/spaces/files/urls/download", ddClient.initTokenHeader(), null, body, DDR_New.class);
+
+            //2、执行下载
+            Map result = (Map) ddrNew.getResult();
+
+            String downloadUri = UtilMap.getString(result, "downloadUri");
+
+            downloadFile(downloadUri,downloadPath);
+
+        }catch (Exception e){
+            throw new RuntimeException(e);
+        }
+    }
+
+    //文件下载到本地
+    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);
+        }
+    }
+
+    //上传钉盘附件
+    private Map uploadDdFile(String spaceId,String parentDentryUuid, String filePath,String unionId) {
+        //获取当前时间戳
+        long beginTimestamp = System.currentTimeMillis();
+        System.out.println("开始上传附件:" + DateUtil.format(new Date(beginTimestamp), "yyyy-MM-dd HH:mm:ss"));
+
+        //文件
+        File file = new File(filePath);
+
+        //获取文件上传信息
+        Map param = new HashMap();
+        param.put("unionId",unionId);
+        Map body = new HashMap();
+        body.put("protocol","HEADER_SIGNATURE");
+        body.put("multipart",false);
+
+        DDR_New ddr = (DDR_New) UtilHttp.doPost("https://api.dingtalk.com/v1.0/storage/spaces/" + spaceId + "/files/uploadInfos/query", ddClient.initTokenHeader(), param, body, DDR_New.class);
+        String uploadKey = ddr.getUploadKey();
+        Map headerSignatureInfo = ddr.getHeaderSignatureInfo();
+        Map<String,String> headers = (Map<String,String>) headerSignatureInfo.get("headers");
+        List<String> resourceUrls = (List<String>) headerSignatureInfo.get("resourceUrls");
+        String resourceUrl = resourceUrls.get(0);
+
+        Map dentry = new HashMap();
+        //使用OSS的header加签方式上传文件
+        try {
+            URL url = new URL(resourceUrl);
+            HttpURLConnection connection = (HttpURLConnection)url.openConnection();
+            if (headers != null) {
+                for (Map.Entry<String, String> entry : headers.entrySet()) {
+                    connection.setRequestProperty(entry.getKey(), entry.getValue());
+                }
+            }
+            connection.setDoOutput(true);
+            connection.setRequestMethod("PUT");
+            connection.setUseCaches(false);
+            connection.setReadTimeout(10000);
+            connection.setConnectTimeout(10000);
+            connection.connect();
+            OutputStream out = connection.getOutputStream();
+            InputStream is = new FileInputStream(file);
+            byte[] b =new byte[1024];
+            int temp;
+            while ((temp=is.read(b))!=-1){
+                out.write(b,0,temp);
+            }
+            out.flush();
+            out.close();
+            int responseCode = connection.getResponseCode();
+            connection.disconnect();
+            if (responseCode == 200) {
+                System.out.println("上传成功");
+            } else {
+                System.out.println("上传失败");
+            }
+            //提交文件
+            Map body2 = new HashMap();
+            Map option = new HashMap();
+            option.put("conflictStrategy","OVERWRITE");
+            body2.put("uploadKey",uploadKey);
+            body2.put("name",file.getName());
+            body2.put("option",option);
+            DDR_New ddrNew = (DDR_New) UtilHttp.doPost("https://api.dingtalk.com/v2.0/storage/spaces/files/"+parentDentryUuid+"/commit", ddClient.initTokenHeader(), param, body2, DDR_New.class);
+            dentry = ddrNew.getDentry();
+
+        }catch (IOException e){
+            log.info("上传文件异常:{}",e);
+        }
+
+        long endTimestamp = System.currentTimeMillis();
+        System.out.println("上传文件结束:" + DateUtil.format(new Date(endTimestamp), "yyyy-MM-dd HH:mm:ss"));
+        System.out.println("上传文件耗时:" + (endTimestamp - beginTimestamp)/1000.0 + "s");
+        return dentry;
+    }
+
+    //钉钉审批单添加评论
+    private void comment(String procInstId,String userId,String text,List<Map> dentries){
+        Map body = new HashMap<>();
+        Map fileMap = new HashMap<>();
+
+        if (Objects.nonNull(dentries)){
+            List<Map> attachments= new ArrayList<>();
+            for (Map dentry : dentries) {
+                Map attachment = new HashMap<>();
+
+                attachment.put("spaceId",dentry.get("spaceId").toString());
+                attachment.put("fileSize",dentry.get("size").toString());
+                attachment.put("fileId",dentry.get("id").toString());
+                attachment.put("fileName",dentry.get("name").toString());
+                attachment.put("fileType",dentry.get("type").toString());
+
+                attachments.add(attachment);
+            }
+            fileMap.put("photos",null);
+            fileMap.put("attachments",attachments);
+        }
+
+        body.put("processInstanceId",procInstId);
+        body.put("text",text);
+        body.put("commentUserId",userId);
+        body.put("file",fileMap);
+
+        UtilHttp.doPost("https://api.dingtalk.com/v1.0/workflow/processInstances/comments",ddClient.initTokenHeader(),null,body);
+    }
+
+    //e签宝-获取文件名称
+    private String getEqbFileName(String fileKey){
+        Map data = (Map) eqbGet(host + "/file/v1/getFileInfo?fileKey="+fileKey);
+
+        return UtilMap.getString(data,"filename");
+    }
+
+    //e签宝-上传附件并转换为pdf
+    public String uploadAndConvertEqbFile(String filePath,String fileName) {
+        try {
+            //获得文件后缀名
+            String suffix = fileName.substring(fileName.lastIndexOf(".")+1);
+
+            //1、生成上传文件链接
+            JSONObject reqBodyObj = new JSONObject(true);
+            reqBodyObj.put("requestID", UUID.randomUUID().toString().replaceAll("-",""));//请求ID,长度:32位,
+            reqBodyObj.put("type", 1);//获取上传链接类型  0为同步上传,适用于100M以内的pdf文件。 1为异步上传,适用于大于100M的pdf文件,以及其他类型的文件:ofd、doc、docx、xls、xlsx、jpg、jpeg、png、zip、rar。
+
+            Map data = (Map) eqbPost(host + "file/v1/generateUploadUrl", reqBodyObj);
+
+            String url = UtilMap.getString(data, "url");
+
+            url = url.replace("http://11.0.11.62:8199/",host);
+
+            //2、上传文件到指定链接
+            Map<String,Object> body = new HashMap<>();
+            body.put("file",fileName);
+
+            Map data2 = eqbUpload(url, body, filePath, fileName);
+            String fileKey = UtilMap.getString(data2, "fileKey");
+
+            //3、判断是否为pdf
+            if(!"pdf".equals(suffix)){
+                //4、文档格式转换
+                Map body2 = new HashMap();
+                body2.put("fileKey", fileKey);
+                body2.put("targetType", "pdf");
+
+                Map map = (Map) eqbPost(host + "file/v1/fileConvert", body2);
+
+                fileKey = UtilMap.getString(map,"convertedFileKey");
+            }
+
+            System.out.println("fileKey: " + fileKey);
+
+            return fileKey;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    //e签宝-get请求
+    private Object eqbGet(String url){
+        try {
+            // 构建待签名字符串
+            String accept = "*/*";
+            String contentType = "application/json; charset=UTF-8";
+
+            // 构建参与请求签名计算的明文
+            int index = url.indexOf("?");
+            String plaintext = index == -1 ? "" : url.substring(index + 1);
+            // 计算请求签名值
+            String reqSignature = sign(plaintext, secret);
+
+            // 构建请求头
+            LinkedHashMap<String, String> header = new LinkedHashMap<>();
+            header.put("X-timevale-project-id", projectId);
+            header.put("X-timevale-signature", reqSignature);
+            header.put("Accept", accept);
+            header.put("Content-Type", contentType);
+
+            // 发送GET请求
+            String resultStr = HTTPHelper.sendGet(url, header, "UTF-8");
+            Map result = (Map) JSONObject.parse(resultStr);
+
+            isSuccess(result);
+
+            Object data = result.get("data");
+
+            return data;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    //e签宝-post请求(application/json)
+    private Object eqbPost(String url,Map body){
+        try {
+            // 请求Body体数据
+            String reqBodyData = JSONObject.toJSONString(body);
+
+            // 计算请求签名值
+            String reqSignature = sign(reqBodyData, secret);
+
+            // 构建请求头
+            LinkedHashMap<String, String> header = new LinkedHashMap<>();
+
+            // 构建待签名字符串
+            header.put("X-timevale-project-id", projectId);
+            header.put("X-timevale-signature", reqSignature);
+            header.put("Accept", "*/*");
+            header.put("Content-Type", "application/json; charset=UTF-8");
+
+            String resultStr = HTTPHelper.sendPOST(url, reqBodyData, header, "UTF-8");
+
+            Map result = (Map) JSONObject.parse(resultStr);
+
+            isSuccess(result);
+
+            Object data = result.get("data");
+
+            return data;
+        }catch (Exception e){
+            throw new RuntimeException(e);
+        }
+    }
+
+    //e签宝-附件上传
+    private Map eqbUpload(String url,Map body,String filePath,String fileName){
+        try {
+            // 构建请求头
+            String reqSignature = sign(JSONObject.toJSONString(body), secret);
+            LinkedHashMap<String, String> header = new LinkedHashMap<>();
+            // 构建待签名字符串
+            header.put("X-timevale-project-id", projectId);
+            header.put("X-timevale-signature", reqSignature);
+            header.put("Accept", "*/*");
+
+            String resultStr = HTTPHelper.uploadFile(url,  "file", filePath, body,  header, "UTF-8");
+
+            Map result = (Map) JSONObject.parse(resultStr);
+
+            isSuccess(result);
+
+            Map data = UtilMap.getMap(result, "data");
+
+            return data;
+        }catch (Exception e){
+            throw new RuntimeException();
+        }
+    }
+
+
+    /**
+     * hmac-sha256签名
+     *
+     * @param content 代签名的内容
+     * @param key     签名的key
+     * @return 签名
+     */
+    private String sign(String content, String key) {
+        byte[] bytes = new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmac(content);
+        return new String(Hex.encodeHex(bytes));
+    }
+
+    //判断e签宝接口返回是否成功
+    private void isSuccess(Map result){
+        int code = UtilMap.getInt(result, "code");
+
+        String message = UtilMap.getString(result, "message");
+
+        if (200 != code || !"成功".equals(message)){
+            throw new RuntimeException(message);
+        }
+    }
 
 }

+ 8 - 2
mjava-boyang/src/main/resources/application-dev.yml

@@ -14,11 +14,17 @@ logging:
 # dingtalk
 dingtalk:
   agentId:
-  appKey:
-  appSecret:
+  appKey: dingt4kem6twzlqehm58
+  appSecret: ZgE_XOfccVlSOcbw3cN0Ad_dJFqBB_PfPPmqJzGTgKXPu5tsh17KibxG7WEB6_hc
   corpId:
   aesKey:
   token:
+  operator: "065965353428672133" #潘麒卿
+  operatorUnionId: AfZv5MOJ80W2STOhUbbOcAiEiE #潘麒卿
+  downloadPath: d:\\
+  spaceId: 27829762189 #钉盘-e签宝
+  parentDentryUuid: y20BglGWO23pGpLOsaALnnz98A7depqY #钉盘-e签宝-签署后文件
+
 
 aliwork:
   appType:

+ 8 - 2
mjava-boyang/src/main/resources/application-prod.yml

@@ -14,11 +14,17 @@ logging:
 # dingtalk
 dingtalk:
   agentId:
-  appKey:
-  appSecret:
+  appKey: dingt4kem6twzlqehm58
+  appSecret: ZgE_XOfccVlSOcbw3cN0Ad_dJFqBB_PfPPmqJzGTgKXPu5tsh17KibxG7WEB6_hc
   corpId:
   aesKey:
   token:
+  operator: 065965353428672133 #潘麒卿
+  operatorUnionId: AfZv5MOJ80W2STOhUbbOcAiEiE #潘麒卿
+  downloadPath: d:\\
+  spaceId: 27829762189 #钉盘-e签宝
+  parentDentryUuid: y20BglGWO23pGpLOsaALnnz98A7depqY #钉盘-e签宝-签署后文件
+
 
 aliwork:
   appType:

+ 92 - 0
mjava-boyang/src/test/java/com/malk/boyang/DdTest.java

@@ -0,0 +1,92 @@
+package com.malk.boyang;
+
+import com.malk.boyang.service.BoyangService;
+import com.malk.server.dingtalk.DDR_New;
+import com.malk.service.dingtalk.DDClient;
+import com.malk.utils.UtilHttp;
+import com.malk.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
+import okhttp3.*;
+import okio.BufferedSink;
+import okio.Okio;
+import okio.Sink;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@SpringBootTest
+@RunWith(SpringRunner.class)
+public class DdTest {
+    @Autowired
+    private DDClient ddClient;
+
+    @Autowired
+    private BoyangService boyangService;
+
+    @Test
+    public void test(){
+        try {
+            String downloadPath = "d:\\iwElAqNqcGcDBgTRBOEF0QNABrB2pIOfLsLZggjsjitQfgUABwAIAAmqcGF5SW52b2ljZQoACwA.jpg";
+
+            /*String processInstanceId = "R9N-KN3tTOyNDTIWbxI7LA01161763691347";
+            String fileId = "201425340171";
+
+            Map body = new HashMap();
+            body.put("processInstanceId",processInstanceId);
+            body.put("fileId",fileId);
+
+            DDR_New ddrNew = (DDR_New) UtilHttp.doPost("https://api.dingtalk.com/v1.0/workflow/processInstances/spaces/files/urls/download", ddClient.initTokenHeader(), null, body, DDR_New.class);
+
+            //2、执行下载
+            Map result = (Map) ddrNew.getResult();*/
+
+//            String downloadUri = UtilMap.getString(result, "downloadUri");
+            String downloadUri = "https://down-cdn.dingtalk.com/ddmedia/iwElAqNqcGcDBgTRBOEF0QNABrB2pIOfLsLZggjsjitQfgUABwAIAAmqcGF5SW52b2ljZQoACwA.jpg";
+
+            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);
+        }
+
+    }
+
+    @Test
+    public void test2(){
+        boyangService.eSignSubmit(UtilMap.map("processInstanceId","9L_PKi71S8W3kL_nftFpXw01161764152519"));
+    }
+}
+

+ 547 - 0
mjava-boyang/src/test/java/com/malk/boyang/EqbTest.java

@@ -0,0 +1,547 @@
+package com.malk.boyang;
+
+import com.alibaba.fastjson.JSONObject;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import com.malk.boyang.service.BoyangService;
+import com.malk.boyang.utils.HTTPHelper;
+import com.malk.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.codec.binary.Hex;
+import org.apache.commons.codec.digest.HmacAlgorithms;
+import org.apache.commons.codec.digest.HmacUtils;
+import org.json.JSONArray;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@Slf4j
+@SpringBootTest
+@RunWith(SpringRunner.class)
+public class EqbTest {
+    @Autowired
+    private BoyangService boyangService;
+
+
+
+    //测试环境
+    // 应用ID
+    final static String projectId = "1000004";
+    // 应用密钥
+    final static String secret = "96Uh7CR83NkN3TA6";
+    // 接口调用域名
+    final static String host = "http://122.227.225.202:9011/";
+
+    //===============================================================================================
+
+    //正式环境
+    /*// 应用ID
+    final static String projectId = "1000003";
+    // 应用密钥
+    final static String secret = "5V6xsY3q8JWZ9Qik";
+    // 接口调用域名
+    final static String host = "https://dzqz.beyond-it-service.com/";*/
+
+
+    /*public static void main(String[] args) {
+        // 请求签名鉴权-POST请求
+        testPost(projectId, secret, host);
+
+        // 请求签名鉴权-GET请求
+//        testGet(projectId, secret, host);
+
+        // 请求签名鉴权-POST请求-文件上传
+//        testUpload(projectId, secret, host);
+
+    }*/
+
+    @Test
+    /***
+     * 请求签名鉴权-POST请求
+     *
+     * @param projectId 项目Id
+     * @param secret 项目密钥
+     * @param host 网关地址
+     */
+    public void testPost() {
+        // 查询查询内部组织详情地址
+        String getInnerOrganizationsDetailApi = "/manage/v1/innerOrganizations/detail";
+        // 查询查询内部组织详情请求地址
+        String getInnerOrganizationsDetailApiUrl = host + getInnerOrganizationsDetailApi;
+
+        try {
+            // 构建请求Body体
+            JSONObject reqBodyObj = new JSONObject(true);
+            reqBodyObj.put("organizationCode", "");
+            reqBodyObj.put("customOrgNo", "");
+            reqBodyObj.put("name", "博洋");
+
+            // 请求Body体数据
+            String reqBodyData = reqBodyObj.toString();
+            // 对请求Body体内的数据计算ContentMD5
+
+            // 构建参与请求签名计算的明文
+            String plaintext = reqBodyData;
+            // 计算请求签名值
+            String reqSignature = sign(plaintext, secret);
+
+            // 构建请求头
+            LinkedHashMap<String, String> header = new LinkedHashMap<>();
+            // 构建待签名字符串
+            String accept = "*/*";
+            String contentType = "application/json; charset=UTF-8";
+            header.put("X-timevale-project-id", projectId);
+            header.put("X-timevale-signature", reqSignature);
+            header.put("Accept", accept);
+            header.put("Content-Type", contentType);
+
+            // 发送POST请求
+            String result = HTTPHelper.sendPOST(getInnerOrganizationsDetailApiUrl, reqBodyData, header, "UTF-8");
+            JSONObject resultObj = JSONObject.parseObject(result);
+            System.out.println("请求返回信息: " + resultObj.toString());
+        } catch (Exception e) {
+            e.printStackTrace();
+            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
+            System.out.println(msg);
+        }
+    }
+
+    @Test
+    /***
+     * 使用文件发起签署(一步发起签署)
+     *
+     * @param projectId 项目Id
+     * @param secret 项目密钥
+     * @param host 网关地址
+     */
+    public void testPost2() {
+
+        String api = "/esign-signs/v1/signFlow/createAndStart";
+
+        String getInnerOrganizationsDetailApiUrl = host + api;
+
+        try {
+            // 构建请求Body体
+            JSONObject reqBodyObj = new JSONObject(true);
+            // 添加基本字段
+            reqBodyObj.put("subject", "测试api直接发起签署");
+            reqBodyObj.put("businessNo", "R9N-KN3tTOyNDTIWbxI7LA01161763691347");
+            reqBodyObj.put("businessTypeCode", "889726e889ab84fea3514748d6df565c");
+            reqBodyObj.put("remark", "测试");
+
+            // 构建initiatorInfo对象
+            JSONObject initiatorInfo = new JSONObject(true);
+            initiatorInfo.put("userCode", "wanghh");
+            initiatorInfo.put("departmentCode", "b60a9c18b8cc4ecc80e30f36b4267a68");
+            initiatorInfo.put("organizationCode", "b60a9c18b8cc4ecc80e30f36b4267a68");
+            reqBodyObj.put("initiatorInfo", initiatorInfo);
+
+            // 添加其他字段
+            reqBodyObj.put("redirectUrl", "https://www.baidu.com");
+            reqBodyObj.put("signNotifyUrl", "http://3eb3815c.r23.cpolar.top/boyang/callback");
+
+            // 构建signFiles数组
+            JSONArray signFiles = new JSONArray();
+            JSONObject signFile = new JSONObject(true);
+            signFile.put("fileKey", "$832b183d-b3ac-4587-9488-553b82e11eec$2419219229");
+            signFile.put("fileOrder", 1);
+            signFiles.put(signFile);
+            reqBodyObj.put("signFiles", signFiles);
+
+            // 构建signerInfos数组
+            JSONArray signerInfos = new JSONArray();
+            JSONObject signerInfo = new JSONObject(true);
+            signerInfo.put("userType", "1");
+            signerInfo.put("userCode", "wanghh");
+            signerInfo.put("departmentCode", "b60a9c18b8cc4ecc80e30f36b4267a68");
+            signerInfo.put("organizationCode", "b60a9c18b8cc4ecc80e30f36b4267a68");
+            signerInfo.put("signNode", 1);
+            signerInfo.put("signMode", "0");
+            signerInfo.put("signOrder", 1);
+            signerInfos.put(signerInfo);
+            reqBodyObj.put("signerInfos", signerInfos);
+
+
+            // 请求Body体数据
+            String reqBodyData = reqBodyObj.toString();
+            // 对请求Body体内的数据计算ContentMD5
+
+            // 构建参与请求签名计算的明文
+            String plaintext = reqBodyData;
+            // 计算请求签名值
+            String reqSignature = sign(plaintext, secret);
+
+            // 构建请求头
+            LinkedHashMap<String, String> header = new LinkedHashMap<>();
+            // 构建待签名字符串
+            String accept = "*/*";
+            String contentType = "application/json; charset=UTF-8";
+            header.put("X-timevale-project-id", projectId);
+            header.put("X-timevale-signature", reqSignature);
+            header.put("Accept", accept);
+            header.put("Content-Type", contentType);
+
+            // 发送POST请求
+            String result = HTTPHelper.sendPOST(getInnerOrganizationsDetailApiUrl, reqBodyData, header, "UTF-8");
+            JSONObject resultObj = JSONObject.parseObject(result);
+            System.out.println("请求返回信息: " + resultObj.toString());
+        } catch (Exception e) {
+            e.printStackTrace();
+            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
+            System.out.println(msg);
+        }
+    }
+
+    /***
+     * 请求签名鉴权-GET请求
+     *
+     * @param projectId 项目id
+     * @param secret 项目密钥
+     * @param host 网关地址
+     */
+    public static void testGet(String projectId, String secret, String host) {
+        // 获取签署地址列表API地址
+        String getSignFlowApi = "/esign-signs/v1/signFlow/signUrls?signFlowId=" + "24210df8420968c1e785a3b7582295b6";
+        // 获取签署地址列表接口请求地址
+        String hostGetSignFlowApi = host + getSignFlowApi;
+
+        try {
+            // 构建待签名字符串
+            String accept = "*/*";
+            String contentType = "application/json; charset=UTF-8";
+
+            // 构建参与请求签名计算的明文
+            int index = getSignFlowApi.indexOf("?");
+            String plaintext = index == -1 ? "" : getSignFlowApi.substring(index + 1);
+            // 计算请求签名值
+            String reqSignature = sign(plaintext, secret);
+
+            // 构建请求头
+            LinkedHashMap<String, String> header = new LinkedHashMap<>();
+            header.put("X-timevale-project-id", projectId);
+            header.put("X-timevale-signature", reqSignature);
+            header.put("Accept", accept);
+            header.put("Content-Type", contentType);
+
+            // 发送GET请求
+            String result = HTTPHelper.sendGet(hostGetSignFlowApi, header, "UTF-8");
+            JSONObject resultObj = JSONObject.parseObject(result);
+            System.out.println("请求返回信息: " + resultObj.toString());
+        } catch (Exception e) {
+            e.printStackTrace();
+            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
+            System.out.println(msg);
+        }
+    }
+
+    /***
+     * 查询电子签署业务模板详情
+     */
+    @Test
+    public void testGet2() {
+
+        String api = "/esign-docs/v1/bizTemplates/889726e889ab84fea3514748d6df565c";
+
+        String hostGetSignFlowApi = host + api;
+
+        try {
+            // 构建待签名字符串
+            String accept = "*/*";
+            String contentType = "application/json; charset=UTF-8";
+
+            // 构建参与请求签名计算的明文
+            int index = api.indexOf("?");
+            String plaintext = index == -1 ? "" : api.substring(index + 1);
+            // 计算请求签名值
+            String reqSignature = sign(plaintext, secret);
+
+            // 构建请求头
+            LinkedHashMap<String, String> header = new LinkedHashMap<>();
+            header.put("X-timevale-project-id", projectId);
+            header.put("X-timevale-signature", reqSignature);
+            header.put("Accept", accept);
+            header.put("Content-Type", contentType);
+
+            // 发送GET请求
+            String result = HTTPHelper.sendGet(hostGetSignFlowApi, header, "UTF-8");
+            JSONObject resultObj = JSONObject.parseObject(result);
+            System.out.println("请求返回信息: " + resultObj.toString());
+        } catch (Exception e) {
+            e.printStackTrace();
+            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
+            System.out.println(msg);
+        }
+    }
+
+
+    @Test
+    public void testMembersList() {
+        // 获取签署地址列表API地址
+        String getSignFlowApi = "/manage/v1/innerOrganizations/members/list";
+        // 获取签署地址列表接口请求地址
+        String hostGetSignFlowApi = host + getSignFlowApi;
+
+        try {
+            // 构建请求Body体
+            JSONObject reqBodyObj = new JSONObject(true);
+            reqBodyObj.put("queryScope", "0");
+            reqBodyObj.put("organizationCode", "b60a9c18b8cc4ecc80e30f36b4267a68");
+            reqBodyObj.put("pageNo", 1);
+            reqBodyObj.put("pageSize", "50");
+
+            // 请求Body体数据
+            String reqBodyData = reqBodyObj.toString();
+            // 对请求Body体内的数据计算ContentMD5
+
+            // 构建参与请求签名计算的明文
+            String plaintext = reqBodyData;
+            // 计算请求签名值
+            String reqSignature = sign(plaintext, secret);
+
+            // 构建请求头
+            LinkedHashMap<String, String> header = new LinkedHashMap<>();
+            // 构建待签名字符串
+            String accept = "*/*";
+            String contentType = "application/json; charset=UTF-8";
+            header.put("X-timevale-project-id", projectId);
+            header.put("X-timevale-signature", reqSignature);
+            header.put("Accept", accept);
+            header.put("Content-Type", contentType);
+
+            // 发送GET请求
+            String result = HTTPHelper.sendPOST(hostGetSignFlowApi,reqBodyData, header, "UTF-8");
+            JSONObject resultObj = JSONObject.parseObject(result);
+            System.out.println("请求返回信息: " + resultObj.toString());
+        } catch (Exception e) {
+            e.printStackTrace();
+            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
+            System.out.println(msg);
+        }
+    }
+
+    @Test
+    public void test4(){
+        boyangService.signed("","");
+    }
+
+    @Test
+    public void uploadEqbFile(){
+        String fileName = "2.png";
+        String filePath = "C:\\Users\\EDY\\Pictures\\2.png";
+        try {
+            //获得文件后缀名
+            String suffix = fileName.substring(fileName.lastIndexOf(".")+1);
+
+            //生成上传文件链接
+            String api = host + "file/v1/generateUploadUrl";
+
+            JSONObject reqBodyObj = new JSONObject(true);
+            reqBodyObj.put("requestID", UUID.randomUUID().toString().replaceAll("-",""));//请求ID,长度:32位,
+            reqBodyObj.put("type", 1);//获取上传链接类型  0为同步上传,适用于100M以内的pdf文件。 1为异步上传,适用于大于100M的pdf文件,以及其他类型的文件:ofd、doc、docx、xls、xlsx、jpg、jpeg、png、zip、rar。
+
+            Map data = eqbPost(api, reqBodyObj);
+
+            String url = UtilMap.getString(data, "url");
+            url = url.replace("http://11.0.11.62:8199/",host);
+
+            // 上传文件到指定链接
+            Map<String,Object> body = new HashMap<>();
+            body.put("file",fileName);
+
+            // 构建请求头
+            String reqSignature2 = sign(JSONObject.toJSONString(body), secret);
+            LinkedHashMap<String, String> header2 = new LinkedHashMap<>();
+            // 构建待签名字符串
+            header2.put("X-timevale-project-id", projectId);
+            header2.put("X-timevale-signature", reqSignature2);
+            header2.put("Accept", "*/*");
+
+            String result2 = HTTPHelper.uploadFile(url,  "file", filePath, body,  header2, "UTF-8");
+            Map parse = (Map) JSONObject.parse(result2);
+
+            Map data1 = UtilMap.getMap(parse, "data");
+            String fileKey = UtilMap.getString(data1, "fileKey");
+
+
+            //若文件不是pdf则需转换
+            if(!"pdf".equals(suffix)){
+                //文档格式转换
+                Map body2 = new HashMap();
+                body2.put("fileKey", fileKey);
+                body2.put("targetType", "pdf");
+
+                Map map = eqbPost(host + "file/v1/fileConvert", body2);
+
+                fileKey = UtilMap.getString(map,"convertedFileKey");
+            }
+
+            System.out.println("fileKey: " + fileKey);
+        } catch (Exception e) {
+            e.printStackTrace();
+            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
+            System.out.println(msg);
+        }
+    }
+
+    private Map eqbPost(String url,Map body){
+        try {
+            // 请求Body体数据
+            String reqBodyData = JSONObject.toJSONString(body);
+
+            // 计算请求签名值
+            String reqSignature = sign(reqBodyData, secret);
+
+            // 构建请求头
+            LinkedHashMap<String, String> header = new LinkedHashMap<>();
+
+            // 构建待签名字符串
+            header.put("X-timevale-project-id", projectId);
+            header.put("X-timevale-signature", reqSignature);
+            header.put("Accept", "*/*");
+            header.put("Content-Type", "application/json; charset=UTF-8");
+
+            String result = HTTPHelper.sendPOST(url, reqBodyData, header, "UTF-8");
+
+            Map resultObj = (Map) JSONObject.parse(result);
+
+            Map data = UtilMap.getMap(resultObj, "data");
+
+            return data;
+        }catch (Exception e){
+            throw new RuntimeException(e);
+        }
+
+    }
+
+    @Test
+    public void test5(){
+        // 构建请求Body体
+        JSONObject reqBodyObj = new JSONObject(true);
+        reqBodyObj.put("hash", "0748da018502f6331f10d64e645bc0b8f20d44cc7d041a9752ce586149b843d7");
+        reqBodyObj.put("filePwd", "");
+
+        // 请求Body体数据
+        String reqBodyData = reqBodyObj.toString();
+        // 对请求Body体内的数据计算ContentMD5
+
+        // 构建参与请求签名计算的明文
+        String plaintext = reqBodyData;
+        // 计算请求签名值
+        String reqSignature = sign(plaintext, secret);
+
+        System.out.println(reqSignature);
+
+        // 构建请求头
+        LinkedHashMap<String, String> header = new LinkedHashMap<>();
+        // 构建待签名字符串
+        String accept = "*/*";
+        String contentType = "application/json; charset=UTF-8";
+        header.put("X-timevale-project-id", projectId);
+        header.put("X-timevale-signature", reqSignature);
+        header.put("Accept", accept);
+        header.put("Content-Type", contentType);
+    }
+
+    /**
+     * hmac-sha256签名
+     *
+     * @param content 代签名的内容
+     * @param key     签名的key
+     * @return 签名
+     */
+    public static String sign(String content, String key) {
+        byte[] bytes = new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmac(content);
+        return new String(Hex.encodeHex(bytes));
+    }
+
+    /**
+     * 计算文件的SHA-256哈希值
+     */
+    public static String calculateSha256(File file) throws Exception {
+        byte[] fileBytes = new byte[(int) file.length()];
+        MessageDigest digest = MessageDigest.getInstance("SHA-256");
+        byte[] hashBytes = digest.digest(fileBytes);
+
+        // 转换为十六进制字符串
+        StringBuilder hexString = new StringBuilder();
+        for (byte b : hashBytes) {
+            String hex = Integer.toHexString(0xff & b);
+            if (hex.length() == 1) hexString.append('0');
+            hexString.append(hex);
+        }
+        return hexString.toString();
+    }
+
+
+    /***
+     * 请求签名鉴权-POST请求
+     *
+     */
+    @Test
+    public void testUpload() {
+        String filePath = "d:\\母婴店.pdf";
+
+        // 文件上传接口
+        String uploadApi = "/file/v1/pdf/uploadAndSpilt";
+//        String uploadApi = "/file/v1/uploadWithAuth";
+        // 文件上传接口请求地址
+        String uploadApiUrl = host + uploadApi;
+
+        try {
+            // 构建请求Body体
+            JSONObject reqBodyObj = new JSONObject(true);
+            reqBodyObj.put("file", "母婴店.pdf");
+
+//            reqBodyObj.put("hash", calculateSha256(new File(filePath)));
+//            reqBodyObj.put("hash", "17070b46957568b378c4c8970beceaf2d50b590ec13852a91f2eac0031bcdf96");
+            reqBodyObj.put("filePwd", "");
+
+            // 请求Body体数据
+            String reqBodyData = reqBodyObj.toString();
+
+            // 构建参与请求签名计算的明文
+            String plaintext = reqBodyData;
+            // 计算请求签名值
+            String reqSignature = sign(plaintext, secret);
+
+//            reqBodyObj.put("file","床上用品店.pdf");
+
+            // 构建文件
+            String fileFieldName = "file";
+
+            // 构建请求头
+            LinkedHashMap<String, String> header = new LinkedHashMap<>();
+            // 构建待签名字符串
+            String accept = "*/*";
+            header.put("X-timevale-project-id", projectId);
+            header.put("X-timevale-signature", reqSignature);
+            header.put("Accept", accept);
+            // 发送POST请求
+            String result = HTTPHelper.uploadFile(uploadApiUrl,  fileFieldName, filePath, reqBodyObj,  header, "UTF-8");
+            JSONObject resultObj = JSONObject.parseObject(result);
+            System.out.println("请求返回信息: " + resultObj.toString());
+        } catch (Exception e) {
+            e.printStackTrace();
+            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
+            System.out.println(msg);
+        }
+    }
+
+
+}

+ 0 - 193
mjava-boyang/src/test/java/com/malk/boyang/Test.java

@@ -1,193 +0,0 @@
-package com.malk.boyang;
-
-import com.alibaba.fastjson.JSONObject;
-import java.text.MessageFormat;
-import java.util.LinkedHashMap;
-
-import com.malk.boyang.utils.HTTPHelper;
-import org.apache.commons.codec.binary.Hex;
-import org.apache.commons.codec.digest.HmacAlgorithms;
-import org.apache.commons.codec.digest.HmacUtils;
-
-public class Test {
-    public static void main(String[] args) {
-        //测试环境
-        // 应用ID
-        /*String projectId = "1000004";
-        // 应用密钥
-        String secret = "96Uh7CR83NkN3TA6";
-        // 接口调用域名
-        String host = "http://122.227.225.202:9011/";*/
-
-        //正式环境
-        // 应用ID
-        String projectId = "1000003";
-        // 应用密钥
-        String secret = "5V6xsY3q8JWZ9Qik";
-        // 接口调用域名
-        String host = "https://dzqz.beyond-it-service.com/";
-
-        // 请求签名鉴权-POST请求
-        testPost(projectId, secret, host);
-
-        // 请求签名鉴权-GET请求
-//        testGet(projectId, secret, host);
-
-        // 请求签名鉴权-POST请求-文件上传
-//        testUpload(projectId, secret, host);
-    }
-
-    /***
-     * 请求签名鉴权-POST请求
-     *
-     * @param projectId 项目Id
-     * @param secret 项目密钥
-     * @param host 网关地址
-     */
-    public static void testPost(String projectId, String secret, String host) {
-        // 查询查询内部组织详情地址
-        String getInnerOrganizationsDetailApi = "/manage/v1/innerOrganizations/detail";
-        // 查询查询内部组织详情请求地址
-        String getInnerOrganizationsDetailApiUrl = host + getInnerOrganizationsDetailApi;
-
-        try {
-            // 构建请求Body体
-            JSONObject reqBodyObj = new JSONObject(true);
-            reqBodyObj.put("organizationCode", "");
-            reqBodyObj.put("customOrgNo", "");
-            reqBodyObj.put("name", "博洋");
-
-            // 请求Body体数据
-            String reqBodyData = reqBodyObj.toString();
-            // 对请求Body体内的数据计算ContentMD5
-
-            // 构建参与请求签名计算的明文
-            String plaintext = reqBodyData;
-            // 计算请求签名值
-            String reqSignature = sign(plaintext, secret);
-
-            // 构建请求头
-            LinkedHashMap<String, String> header = new LinkedHashMap<>();
-            // 构建待签名字符串
-            String accept = "*/*";
-            String contentType = "application/json; charset=UTF-8";
-            header.put("X-timevale-project-id", projectId);
-            header.put("X-timevale-signature", reqSignature);
-            header.put("Accept", accept);
-            header.put("Content-Type", contentType);
-
-            // 发送POST请求
-            String result = HTTPHelper.sendPOST(getInnerOrganizationsDetailApiUrl, reqBodyData, header, "UTF-8");
-            JSONObject resultObj = JSONObject.parseObject(result);
-            System.out.println("请求返回信息: " + resultObj.toString());
-        } catch (Exception e) {
-            e.printStackTrace();
-            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
-            System.out.println(msg);
-        }
-    }
-
-    /***
-     * 请求签名鉴权-GET请求
-     *
-     * @param projectId 项目id
-     * @param secret 项目密钥
-     * @param host 网关地址
-     */
-    public static void testGet(String projectId, String secret, String host) {
-        // 获取签署地址列表API地址
-        String getSignFlowApi = "/esign-signs/v1/signFlow/signUrls?signFlowId=" + "24210df8420968c1e785a3b7582295b6";
-        // 获取签署地址列表接口请求地址
-        String hostGetSignFlowApi = host + getSignFlowApi;
-
-        try {
-            // 构建待签名字符串
-            String accept = "*/*";
-            String contentType = "application/json; charset=UTF-8";
-
-            // 构建参与请求签名计算的明文
-            int index = getSignFlowApi.indexOf("?");
-            String plaintext = index == -1 ? "" : getSignFlowApi.substring(index + 1);
-            // 计算请求签名值
-            String reqSignature = sign(plaintext, secret);
-
-            // 构建请求头
-            LinkedHashMap<String, String> header = new LinkedHashMap<>();
-            header.put("X-timevale-project-id", projectId);
-            header.put("X-timevale-signature", reqSignature);
-            header.put("Accept", accept);
-            header.put("Content-Type", contentType);
-
-            // 发送GET请求
-            String result = HTTPHelper.sendGet(hostGetSignFlowApi, header, "UTF-8");
-            JSONObject resultObj = JSONObject.parseObject(result);
-            System.out.println("请求返回信息: " + resultObj.toString());
-        } catch (Exception e) {
-            e.printStackTrace();
-            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
-            System.out.println(msg);
-        }
-    }
-
-    /**
-     * hmac-sha256签名
-     *
-     * @param content 代签名的内容
-     * @param key     签名的key
-     * @return 签名
-     */
-    public static String sign(String content, String key) {
-        byte[] bytes = new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmac(content);
-        return new String(Hex.encodeHex(bytes));
-    }
-
-
-    /***
-     * 请求签名鉴权-POST请求
-     *
-     * @param projectId 项目Id
-     * @param secret 项目密钥
-     * @param host 网关地址
-     */
-    public static void testUpload(String projectId, String secret, String host) {
-        // 文件上传接口
-        String uploadApi = "/file/v1/pdf/uploadAndSpilt";
-        // 文件上传接口请求地址
-        String uploadApiUrl = host + uploadApi;
-
-        try {
-            // 构建请求Body体
-            JSONObject reqBodyObj = new JSONObject(true);
-            reqBodyObj.put("file", "测试文件密码123456.pdf");
-            reqBodyObj.put("filePwd", "123456");
-
-            // 请求Body体数据
-            String reqBodyData = reqBodyObj.toString();
-
-            // 构建参与请求签名计算的明文
-            String plaintext = reqBodyData;
-            // 计算请求签名值
-            String reqSignature = sign(plaintext, secret);
-
-            // 构建文件
-            String filePath = "/xxx/xxx/测试文件密码123456.pdf";
-            String fileFieldName = "file";
-
-            // 构建请求头
-            LinkedHashMap<String, String> header = new LinkedHashMap<>();
-            // 构建待签名字符串
-            String accept = "*/*";
-            header.put("X-timevale-project-id", projectId);
-            header.put("X-timevale-signature", reqSignature);
-            header.put("Accept", accept);
-            // 发送POST请求
-            String result = HTTPHelper.uploadFile(uploadApiUrl,  fileFieldName, filePath, reqBodyObj,  header, "UTF-8");
-            JSONObject resultObj = JSONObject.parseObject(result);
-            System.out.println("请求返回信息: " + resultObj.toString());
-        } catch (Exception e) {
-            e.printStackTrace();
-            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
-            System.out.println(msg);
-        }
-    }
-}