BoyangServiceImpl.java 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777
  1. package com.malk.boyang.service.impl;
  2. import cn.hutool.core.date.DateUtil;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.malk.boyang.service.BoyangService;
  5. import com.malk.boyang.utils.HTTPHelper;
  6. import com.malk.server.common.McR;
  7. import com.malk.server.dingtalk.DDConf;
  8. import com.malk.server.dingtalk.DDR_New;
  9. import com.malk.service.dingtalk.*;
  10. import com.malk.utils.UtilHttp;
  11. import com.malk.utils.UtilMap;
  12. import lombok.extern.slf4j.Slf4j;
  13. import org.apache.commons.codec.binary.Hex;
  14. import org.apache.commons.codec.digest.HmacAlgorithms;
  15. import org.apache.commons.codec.digest.HmacUtils;
  16. import org.apache.logging.log4j.util.Strings;
  17. import org.springframework.beans.factory.annotation.Autowired;
  18. import org.springframework.beans.factory.annotation.Value;
  19. import org.springframework.scheduling.annotation.Async;
  20. import org.springframework.stereotype.Service;
  21. import java.io.*;
  22. import java.net.HttpURLConnection;
  23. import java.net.URL;
  24. import java.util.*;
  25. @Slf4j
  26. @Service
  27. public class BoyangServiceImpl implements BoyangService {
  28. @Autowired
  29. private DDClient ddClient;
  30. @Autowired
  31. private DDConf ddConf;
  32. @Autowired
  33. private DDClient_Workflow ddClient_workflow;
  34. @Autowired
  35. private DDClient_Personnel ddClient_personnel;
  36. @Value("${dingtalk.downloadPath}")
  37. private String downloadPath;
  38. @Value("${dingtalk.operatorUnionId}")
  39. private String operatorUnionId;
  40. @Value("${dingtalk.operator}")
  41. private String operator;
  42. @Value("${dingtalk.spaceId}")
  43. private String spaceId;
  44. @Value("${dingtalk.parentDentryUuid}")
  45. private String parentDentryUuid;
  46. /*//测试环境
  47. final static String projectId = "1000004";// 应用ID
  48. final static String secret = "96Uh7CR83NkN3TA6";// 应用密钥
  49. final static String businessTypeCode = "889726e889ab84fea3514748d6df565c";// 钉钉对接测试业务模板
  50. final static String organizationCode = "b60a9c18b8cc4ecc80e30f36b4267a68";// 宁波博洋家纺集团有限公司
  51. final static String host = "http://122.227.225.202:9011/";// 接口调用域名
  52. final static String intranet_host = "http://11.0.11.62/";// 接口调用域名(内网)
  53. final static String signerUser = "wangze";// 签署人
  54. final static String uploadFileUrlHost = "http://11.0.11.62:8199/";// 返回的上传文件url host*/
  55. //正式环境
  56. final static String projectId = "1000003";// 应用ID
  57. final static String secret = "5V6xsY3q8JWZ9Qik";// 应用密钥
  58. final static String businessTypeCode = "f5e84fdb04ef4ead57f37e2a60729066";// 钉钉OA对接业务模板
  59. final static String organizationCode = "0c8dd6496e7f4d228ec033aeef95a526";// 宁波博洋家纺集团有限公司
  60. final static String host = "https://dzqz.beyond-it-service.com/";// 接口调用域名
  61. final static String intranet_host = "http://11.0.11.82/";// 接口调用域名(内网)
  62. final static String signerUser = "22060093";// 签署人
  63. final static String uploadFileUrlHost = "http://11.0.11.82:8199/";// 返回的上传文件url host
  64. @Override
  65. public McR eSignSubmit(Map map) {
  66. String processInstanceId = UtilMap.getString(map, "processInstanceId");
  67. Map result = ddClient_workflow.getProcessInstanceId(ddClient.getAccessToken(), processInstanceId);
  68. List<Map> formComponentValues = UtilMap.getList(result, "formComponentValues");
  69. List<Map<String,String>> fileList = new ArrayList<>();
  70. String subject = "";
  71. String remark = "";
  72. String url = "https://aflow.dingtalk.com/dingtalk/web/query/pchomepage.htm?from=oflow&op=true&corpid=ding76a1e955807327f7f5bf40eda33b7ba0#/plainapproval?procInstId="+processInstanceId;
  73. List<String> sealTypeCodeList = new ArrayList<>();
  74. List<Map> companyList = new ArrayList<>();
  75. for (Map formComponentValue : formComponentValues) {
  76. String id = UtilMap.getString(formComponentValue, "id");
  77. switch (id){
  78. case "TextField-K2AD4O5B"://文件名称
  79. subject = UtilMap.getString(formComponentValue, "value");
  80. //将subject里的"/"替换为","
  81. subject = subject.replaceAll("/",",");
  82. break;
  83. case "DDSelectField_RIHDKAA2UK00"://文件类型
  84. String fileType = UtilMap.getString(formComponentValue, "value");
  85. break;
  86. case "DDSelectField_1G1RJG8MDU9S0"://合同/协议类文件
  87. String htxywj = UtilMap.getString(formComponentValue, "value");
  88. break;
  89. case "DDSelectField_28JHJ0TGPN6S"://是否需要骑缝章
  90. String isQifeng = UtilMap.getString(formComponentValue, "value");
  91. break;
  92. case "TextField_1P4TDG767SRK0"://文件份数
  93. String fileQty = UtilMap.getString(formComponentValue, "value");
  94. break;
  95. case "DDMultiSelectField_1L3KU3TLX6PS0"://印章所属公司
  96. String companyStr = UtilMap.getString(formComponentValue, "extValue");
  97. companyList = (List<Map>) JSONObject.parse(companyStr);
  98. break;
  99. case "DDMultiSelectField_1FW3TFDTJ6V40"://印章类型
  100. String yzlxStr = UtilMap.getString(formComponentValue, "value");
  101. List<String> yzlxList = (List<String>) JSONObject.parse(yzlxStr);
  102. for (String yzlx : yzlxList) {
  103. switch (yzlx){
  104. case "公章":sealTypeCodeList.add("PUBLIC");break;
  105. case "合同章":sealTypeCodeList.add("CONTRACT");break;
  106. case "财务章":sealTypeCodeList.add("FINANCE");break;
  107. case "其他":sealTypeCodeList.add("COMMON");break;
  108. case "人事专用章":sealTypeCodeList.add("PERSONNEL");break;
  109. case "法人章":sealTypeCodeList.add("LEGAL-PERSON-SEAL");break;
  110. default:break;
  111. }
  112. }
  113. break;
  114. case "DDSelectField_1JL8JW2HM5PC0"://用印方式
  115. String yyfs = UtilMap.getString(formComponentValue, "value");
  116. if (!"电子签章".equals(yyfs)){
  117. // return McR.success("非电子签章无需处理");
  118. }
  119. break;
  120. case "TextField_17O0AUUY9L6K0"://签署备注
  121. remark = UtilMap.getString(formComponentValue, "value");
  122. break;
  123. case "DDAttachment_1V002NDXYVKW0"://附件
  124. String attachmentListStr = UtilMap.getString(formComponentValue, "value");
  125. List<Map> attachmentList = (List<Map>) JSONObject.parse(attachmentListStr);
  126. for (Map attachment : attachmentList) {
  127. String fileId = UtilMap.getString(attachment, "fileId");
  128. String fileName = UtilMap.getString(attachment, "fileName");
  129. //下载钉盘文件
  130. String filePath = downloadPath + fileName;
  131. downloadDdFile(processInstanceId,fileId,filePath);
  132. Map fileMap = new HashMap();
  133. fileMap.put("filePath", filePath);
  134. fileMap.put("fileName", fileName);
  135. fileList.add(fileMap);
  136. }
  137. break;
  138. }
  139. }
  140. //查询钉钉用户信息
  141. String name = "";
  142. String mobile = "";
  143. String originatorUserId = UtilMap.getString(result, "originatorUserId");
  144. List<Map> employeeInfos = ddClient_personnel.getEmployeeInfos(ddClient.getAccessToken(), Arrays.asList(originatorUserId), ddConf.getAgentId(), Arrays.asList("sys00-name", "sys00-mobile"));
  145. Map employeeInfo = employeeInfos.get(0);
  146. List<Map> fieldDataList = UtilMap.getList(employeeInfo, "field_data_list");
  147. for (Map fieldData : fieldDataList) {
  148. String fieldCode = UtilMap.getString(fieldData, "field_code");
  149. List<Map> fieldValueList = UtilMap.getList(fieldData, "field_value_list");
  150. switch (fieldCode){
  151. case "sys00-name":
  152. name = UtilMap.getString(fieldValueList.get(0),"value");
  153. break;
  154. case "sys00-mobile":
  155. mobile = UtilMap.getString(fieldValueList.get(0),"value").replace("+86-","");
  156. break;
  157. default:break;
  158. }
  159. }
  160. String eqbUserCode = "";
  161. //查询钉钉用户在e签宝是否存在
  162. Map body = new HashMap();
  163. body.put("name", name);
  164. body.put("mobile", mobile);
  165. List<Map> eqbUsers = (List<Map>) eqbPost(host + "manage/v1/innerUsers/detail", body);
  166. if (!eqbUsers.isEmpty()){
  167. Map eqbUser = eqbUsers.get(0);
  168. eqbUserCode = UtilMap.getString(eqbUser, "userCode");
  169. }else {
  170. //新增e签宝用户
  171. Map eqbUser = new HashMap();
  172. eqbUser.put("name", name);
  173. eqbUser.put("mobile", mobile);
  174. eqbUser.put("customAccountNo", mobile);
  175. eqbUser.put("mainOrganizationCode", organizationCode);//默认组织账号
  176. Map map1 = (Map) eqbPost(host + "manage/v1/innerUsers/create",Arrays.asList(eqbUser));
  177. List<Map> successData = UtilMap.getList(map1, "successData");
  178. eqbUserCode = UtilMap.getString(successData.get(0), "userCode");
  179. }
  180. // 创建主Map
  181. Map<String, Object> requestMap = new HashMap<>();
  182. // 1. 基本字段
  183. requestMap.put("subject", subject);
  184. requestMap.put("businessNo", processInstanceId);
  185. requestMap.put("businessTypeCode", businessTypeCode);
  186. requestMap.put("remark", remark);
  187. // requestMap.put("redirectUrl", url);
  188. // 2. manualConfig 嵌套对象
  189. Map<String, Object> manualConfig = new HashMap<>();
  190. manualConfig.put("startMode", 1);
  191. manualConfig.put("finishMode", 0);
  192. // signingAreaPageConfig 子对象
  193. Map<String, Object> signingAreaPageConfig = new HashMap<>();
  194. signingAreaPageConfig.put("showStartButton", 1);
  195. manualConfig.put("signingAreaPageConfig", signingAreaPageConfig);
  196. requestMap.put("manualConfig", manualConfig);
  197. // 3. initiatorInfo 嵌套对象
  198. Map<String, Object> initiatorInfo = new HashMap<>();
  199. initiatorInfo.put("userCode", eqbUserCode);
  200. /*initiatorInfo.put("customAccountNo", "");
  201. initiatorInfo.put("departmentCode", "");
  202. initiatorInfo.put("customDepartmentNo", "");
  203. initiatorInfo.put("organizationCode", "");
  204. initiatorInfo.put("customOrgNo", "");*/
  205. requestMap.put("initiatorInfo", initiatorInfo);
  206. // 4. signFiles 列表
  207. List<Map<String, Object>> signFiles = new ArrayList<>();
  208. for (int i = 0; i < fileList.size(); i++) {
  209. String fileKey = uploadAndConvertEqbFile(fileList.get(i).get("filePath"), fileList.get(i).get("fileName"));
  210. Map<String, Object> file = new HashMap<>();
  211. file.put("fileKey", fileKey);
  212. file.put("fileOrder", i + 1);
  213. signFiles.add(file);
  214. }
  215. requestMap.put("signFiles", signFiles);
  216. // 5. signerInfos 列表
  217. List<Map<String, Object>> signerInfos = new ArrayList<>();
  218. for (int i = 0; i < companyList.size(); i++) {
  219. Map<String, Object> signer = new HashMap<>();
  220. signer.put("userType", "1");
  221. signer.put("userCode", signerUser);
  222. signer.put("organizationCode", UtilMap.getString(companyList.get(i),"key"));
  223. signer.put("signNode", 1);
  224. signer.put("signMode", "0");
  225. signer.put("signOrder", i + 1);
  226. // signer.put("sealTypeCode", String.join(",",sealTypeCodeList));
  227. signerInfos.add(signer);
  228. }
  229. requestMap.put("signerInfos", signerInfos);
  230. // 打印结果(可选)
  231. System.out.println(requestMap);
  232. //使用文件发起签署(一步发起签署)
  233. Map data = (Map) eqbPost(host + "/esign-signs/v1/signFlow/createAndStart", requestMap);
  234. //签署区设置地址回写评论
  235. Map manualConfig1 = UtilMap.getMap(data, "manualConfig");
  236. Map signingAreaPageInfos = UtilMap.getMap(manualConfig1, "signingAreaPageInfos");
  237. String signingAreaPageUrl = UtilMap.getString(signingAreaPageInfos, "signingAreaPageUrl");
  238. String newSigningAreaPageUrl = signingAreaPageUrl.replace(intranet_host,host);
  239. comment(processInstanceId,originatorUserId,"签署区设置地址:"+newSigningAreaPageUrl,null);
  240. return McR.success();
  241. }
  242. @Async
  243. @Override
  244. public void signed(String processInstanceId,String signFlowId) {
  245. try {
  246. Map result = ddClient_workflow.getProcessInstanceId(ddClient.getAccessToken(), processInstanceId);
  247. String originatorUserId = UtilMap.getString(result, "originatorUserId");
  248. // 获取签署流程进度详情
  249. Map data = (Map) eqbGet(host + "/esign-signs/v1/signFlow/signDetail?signFlowId=" + signFlowId);
  250. List<Map> signFiles = UtilMap.getList(data, "signFiles");
  251. for (Map signFile : signFiles) {
  252. String fileKey = UtilMap.getString(signFile, "fileKey");
  253. String signDownloadOuterUrl = UtilMap.getString(signFile, "signDownloadOuterUrl");
  254. String fileName = getEqbFileName(fileKey);
  255. int suffixIndex = fileName.lastIndexOf(".");
  256. String signedFileName = fileName.substring(0, suffixIndex) + "(已签署)" + fileName.substring(suffixIndex);
  257. //todo 方案1、评论签署后附件下载链接
  258. // comment(processInstanceId,userId,"接口测试 "+ "已签署,签署文件下载地址:" + signDownloadOuterUrl,null);
  259. //方案2、评论签署后附件
  260. //签署后文件下载到本地
  261. downloadFile(signDownloadOuterUrl,downloadPath + signedFileName);
  262. //签署后文件上传到钉盘
  263. Map dentry = uploadDdFile(spaceId, parentDentryUuid, downloadPath + signedFileName, operatorUnionId);
  264. //审批单添加评论
  265. comment(processInstanceId,originatorUserId,fileName + "已签署",Arrays.asList(dentry));
  266. }
  267. //自动通过节点
  268. List<Map> tasks = UtilMap.getList(result, "tasks");
  269. for (Map task : tasks) {
  270. String activityId = UtilMap.getString(task, "activityId");
  271. //e签宝签署节点id:f0e3_8ef9
  272. if ("f0e3_8ef9".equals(activityId)){
  273. long taskId = UtilMap.getLong(task, "taskId");
  274. String userId = UtilMap.getString(task, "userId");
  275. Map body = new HashMap();
  276. body.put("processInstanceId",processInstanceId);
  277. body.put("remark","签署完成自动通过");
  278. body.put("result","agree");
  279. body.put("actionerUserId",userId);
  280. body.put("taskId",taskId);
  281. UtilHttp.doPost("https://api.dingtalk.com/v1.0/workflow/processInstances/execute", ddClient.initTokenHeader(), null, body);
  282. return;
  283. }
  284. }
  285. } catch (Exception e) {
  286. throw new RuntimeException(e);
  287. }
  288. }
  289. @Override
  290. public McR getOrganization(String name) {
  291. if (Strings.isBlank(name)){
  292. return McR.success(new ArrayList<>());
  293. }
  294. Map body = new HashMap();
  295. body.put("name",name);
  296. List<Map> data = (List<Map>) eqbPost(host + "manage/v1/innerOrganizations/detail",body);
  297. List<Map> options = new ArrayList<>();
  298. for (Map datum : data) {
  299. String organizationType = UtilMap.getString(datum, "organizationType");
  300. if ("COMPANY".equals(organizationType)){
  301. String organizationName = UtilMap.getString(datum, "name");
  302. String organizationCode = UtilMap.getString(datum, "organizationCode");
  303. Map option = new HashMap();
  304. option.put("label",organizationName);
  305. option.put("value",organizationCode);
  306. options.add(option);
  307. }
  308. }
  309. //options按label排序
  310. options.sort(Comparator.comparing(m -> UtilMap.getString(m, "label")));
  311. return McR.success(options);
  312. }
  313. @Override
  314. public void start(String processInstanceId,String signFlowId) {
  315. try {
  316. Map result = ddClient_workflow.getProcessInstanceId(ddClient.getAccessToken(), processInstanceId);
  317. String originatorUserId = UtilMap.getString(result, "originatorUserId");
  318. //获取签署地址列表
  319. Map eqbData = (Map) eqbGet(host + "/esign-signs/v1/signFlow/signUrls?signFlowId=" + signFlowId);
  320. Map signUrlInfo = ((List<Map>) UtilMap.getList(eqbData, "signUrlInfos")).get(0);
  321. String signUrlShort = UtilMap.getString(signUrlInfo, "signUrlShort");
  322. //审批单添加评论
  323. comment(processInstanceId,originatorUserId,"签署地址:" + signUrlShort,null);
  324. //自动通过节点
  325. List<Map> tasks = UtilMap.getList(result, "tasks");
  326. for (Map task : tasks) {
  327. String activityId = UtilMap.getString(task, "activityId");
  328. //e签宝设置签署区节点id:802c_7eaf
  329. if ("802c_7eaf".equals(activityId)){
  330. long taskId = UtilMap.getLong(task, "taskId");
  331. String userId = UtilMap.getString(task, "userId");
  332. Map body = new HashMap();
  333. body.put("processInstanceId",processInstanceId);
  334. body.put("remark","签署区设置完成自动通过");
  335. body.put("result","agree");
  336. body.put("actionerUserId",userId);
  337. body.put("taskId",taskId);
  338. UtilHttp.doPost("https://api.dingtalk.com/v1.0/workflow/processInstances/execute", ddClient.initTokenHeader(), null, body);
  339. return;
  340. }
  341. }
  342. } catch (Exception e) {
  343. throw new RuntimeException(e);
  344. }
  345. }
  346. //下载钉钉OA审批单附件
  347. private void downloadDdFile(String processInstanceId,String fileId,String downloadPath){
  348. try {
  349. Map body = new HashMap();
  350. body.put("processInstanceId",processInstanceId);
  351. body.put("fileId",fileId);
  352. 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);
  353. //2、执行下载
  354. Map result = (Map) ddrNew.getResult();
  355. String downloadUri = UtilMap.getString(result, "downloadUri");
  356. downloadFile(downloadUri,downloadPath);
  357. }catch (Exception e){
  358. throw new RuntimeException(e);
  359. }
  360. }
  361. //文件下载到本地
  362. private void downloadFile(String downloadUri,String downloadPath){
  363. try {
  364. URL url = new URL(downloadUri);
  365. HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
  366. int responseCode = httpConn.getResponseCode();
  367. // 检查HTTP响应代码是否为200
  368. if (responseCode == HttpURLConnection.HTTP_OK) {
  369. InputStream inputStream = httpConn.getInputStream();
  370. FileOutputStream outputStream = new FileOutputStream(downloadPath);
  371. byte[] buffer = new byte[4096];
  372. int bytesRead = -1;
  373. while ((bytesRead = inputStream.read(buffer)) != -1) {
  374. outputStream.write(buffer, 0, bytesRead);
  375. }
  376. outputStream.close();
  377. inputStream.close();
  378. } else {
  379. System.out.println("无法下载文件。HTTP响应代码: " + responseCode);
  380. }
  381. httpConn.disconnect();
  382. }catch (Exception e){
  383. throw new RuntimeException(e);
  384. }
  385. }
  386. //上传钉盘附件
  387. private Map uploadDdFile(String spaceId,String parentDentryUuid, String filePath,String unionId) {
  388. //获取当前时间戳
  389. long beginTimestamp = System.currentTimeMillis();
  390. System.out.println("开始上传附件:" + DateUtil.format(new Date(beginTimestamp), "yyyy-MM-dd HH:mm:ss"));
  391. //文件
  392. File file = new File(filePath);
  393. //获取文件上传信息
  394. Map param = new HashMap();
  395. param.put("unionId",unionId);
  396. Map body = new HashMap();
  397. body.put("protocol","HEADER_SIGNATURE");
  398. body.put("multipart",false);
  399. 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);
  400. String uploadKey = ddr.getUploadKey();
  401. Map headerSignatureInfo = ddr.getHeaderSignatureInfo();
  402. Map<String,String> headers = (Map<String,String>) headerSignatureInfo.get("headers");
  403. List<String> resourceUrls = (List<String>) headerSignatureInfo.get("resourceUrls");
  404. String resourceUrl = resourceUrls.get(0);
  405. Map dentry = new HashMap();
  406. //使用OSS的header加签方式上传文件
  407. try {
  408. URL url = new URL(resourceUrl);
  409. HttpURLConnection connection = (HttpURLConnection)url.openConnection();
  410. if (headers != null) {
  411. for (Map.Entry<String, String> entry : headers.entrySet()) {
  412. connection.setRequestProperty(entry.getKey(), entry.getValue());
  413. }
  414. }
  415. connection.setDoOutput(true);
  416. connection.setRequestMethod("PUT");
  417. connection.setUseCaches(false);
  418. connection.setReadTimeout(10000);
  419. connection.setConnectTimeout(10000);
  420. connection.connect();
  421. OutputStream out = connection.getOutputStream();
  422. InputStream is = new FileInputStream(file);
  423. byte[] b =new byte[1024];
  424. int temp;
  425. while ((temp=is.read(b))!=-1){
  426. out.write(b,0,temp);
  427. }
  428. out.flush();
  429. out.close();
  430. int responseCode = connection.getResponseCode();
  431. connection.disconnect();
  432. if (responseCode == 200) {
  433. System.out.println("上传成功");
  434. } else {
  435. System.out.println("上传失败");
  436. }
  437. //提交文件
  438. Map body2 = new HashMap();
  439. Map option = new HashMap();
  440. option.put("conflictStrategy","OVERWRITE");
  441. body2.put("uploadKey",uploadKey);
  442. body2.put("name",file.getName());
  443. body2.put("option",option);
  444. 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);
  445. dentry = ddrNew.getDentry();
  446. }catch (IOException e){
  447. log.info("上传文件异常:{}",e);
  448. }
  449. long endTimestamp = System.currentTimeMillis();
  450. System.out.println("上传文件结束:" + DateUtil.format(new Date(endTimestamp), "yyyy-MM-dd HH:mm:ss"));
  451. System.out.println("上传文件耗时:" + (endTimestamp - beginTimestamp)/1000.0 + "s");
  452. return dentry;
  453. }
  454. //钉钉审批单添加评论
  455. private void comment(String procInstId,String userId,String text,List<Map> dentries){
  456. Map body = new HashMap<>();
  457. Map fileMap = new HashMap<>();
  458. if (Objects.nonNull(dentries)){
  459. List<Map> attachments= new ArrayList<>();
  460. for (Map dentry : dentries) {
  461. Map attachment = new HashMap<>();
  462. attachment.put("spaceId",dentry.get("spaceId").toString());
  463. attachment.put("fileSize",dentry.get("size").toString());
  464. attachment.put("fileId",dentry.get("id").toString());
  465. attachment.put("fileName",dentry.get("name").toString());
  466. attachment.put("fileType",dentry.get("type").toString());
  467. attachments.add(attachment);
  468. }
  469. fileMap.put("photos",null);
  470. fileMap.put("attachments",attachments);
  471. }
  472. body.put("processInstanceId",procInstId);
  473. body.put("text",text);
  474. body.put("commentUserId",userId);
  475. body.put("file",fileMap);
  476. UtilHttp.doPost("https://api.dingtalk.com/v1.0/workflow/processInstances/comments",ddClient.initTokenHeader(),null,body);
  477. }
  478. //e签宝-获取文件名称
  479. private String getEqbFileName(String fileKey){
  480. Map data = (Map) eqbGet(host + "/file/v1/getFileInfo?fileKey="+fileKey);
  481. return UtilMap.getString(data,"filename");
  482. }
  483. //e签宝-上传附件并转换为pdf
  484. public String uploadAndConvertEqbFile(String filePath,String fileName) {
  485. try {
  486. //获得文件后缀名
  487. String suffix = fileName.substring(fileName.lastIndexOf(".")+1);
  488. //1、生成上传文件链接
  489. JSONObject reqBodyObj = new JSONObject(true);
  490. reqBodyObj.put("requestID", UUID.randomUUID().toString().replaceAll("-",""));//请求ID,长度:32位,
  491. reqBodyObj.put("type", 1);//获取上传链接类型 0为同步上传,适用于100M以内的pdf文件。 1为异步上传,适用于大于100M的pdf文件,以及其他类型的文件:ofd、doc、docx、xls、xlsx、jpg、jpeg、png、zip、rar。
  492. Map data = (Map) eqbPost(host + "file/v1/generateUploadUrl", reqBodyObj);
  493. String url = UtilMap.getString(data, "url");
  494. url = url.replace(uploadFileUrlHost,host);
  495. //2、上传文件到指定链接
  496. Map<String,Object> body = new HashMap<>();
  497. body.put("file",fileName);
  498. Map data2 = eqbUpload(url, body, filePath, fileName);
  499. String fileKey = UtilMap.getString(data2, "fileKey");
  500. //3、判断是否为pdf
  501. if(!"pdf".equals(suffix)){
  502. //4、文档格式转换
  503. Map body2 = new HashMap();
  504. body2.put("fileKey", fileKey);
  505. body2.put("targetType", "pdf");
  506. Map map = (Map) eqbPost(host + "file/v1/fileConvert", body2);
  507. fileKey = UtilMap.getString(map,"convertedFileKey");
  508. }
  509. System.out.println("fileKey: " + fileKey);
  510. return fileKey;
  511. } catch (Exception e) {
  512. throw new RuntimeException(e);
  513. }
  514. }
  515. //e签宝-get请求
  516. private Object eqbGet(String url){
  517. try {
  518. // 构建待签名字符串
  519. String accept = "*/*";
  520. String contentType = "application/json; charset=UTF-8";
  521. // 构建参与请求签名计算的明文
  522. int index = url.indexOf("?");
  523. String plaintext = index == -1 ? "" : url.substring(index + 1);
  524. // 计算请求签名值
  525. String reqSignature = sign(plaintext, secret);
  526. // 构建请求头
  527. LinkedHashMap<String, String> header = new LinkedHashMap<>();
  528. header.put("X-timevale-project-id", projectId);
  529. header.put("X-timevale-signature", reqSignature);
  530. header.put("Accept", accept);
  531. header.put("Content-Type", contentType);
  532. // 发送GET请求
  533. log.info("eqb请求入参,url:{},header:{}",url,header);
  534. String resultStr = HTTPHelper.sendGet(url, header, "UTF-8");
  535. log.info("eqb请求响应:{}",resultStr);
  536. Map result = (Map) JSONObject.parse(resultStr);
  537. isSuccess(result);
  538. Object data = result.get("data");
  539. return data;
  540. } catch (Exception e) {
  541. throw new RuntimeException(e);
  542. }
  543. }
  544. //e签宝-post请求(application/json)
  545. private Object eqbPost(String url,Object body){
  546. try {
  547. // 请求Body体数据
  548. String reqBodyData = JSONObject.toJSONString(body);
  549. // 计算请求签名值
  550. String reqSignature = sign(reqBodyData, secret);
  551. // 构建请求头
  552. LinkedHashMap<String, String> header = new LinkedHashMap<>();
  553. // 构建待签名字符串
  554. header.put("X-timevale-project-id", projectId);
  555. header.put("X-timevale-signature", reqSignature);
  556. header.put("Accept", "*/*");
  557. header.put("Content-Type", "application/json; charset=UTF-8");
  558. log.info("eqb请求入参,url:{},reqBodyData:{},header:{}",url,reqBodyData,header);
  559. String resultStr = HTTPHelper.sendPOST(url, reqBodyData, header, "UTF-8");
  560. log.info("eqb请求响应:{}",resultStr);
  561. Map result = (Map) JSONObject.parse(resultStr);
  562. isSuccess(result);
  563. Object data = result.get("data");
  564. return data;
  565. }catch (Exception e){
  566. throw new RuntimeException(e);
  567. }
  568. }
  569. //e签宝-附件上传
  570. private Map eqbUpload(String url,Map body,String filePath,String fileName){
  571. try {
  572. // 构建请求头
  573. String reqSignature = sign(JSONObject.toJSONString(body), secret);
  574. LinkedHashMap<String, String> header = new LinkedHashMap<>();
  575. // 构建待签名字符串
  576. header.put("X-timevale-project-id", projectId);
  577. header.put("X-timevale-signature", reqSignature);
  578. header.put("Accept", "*/*");
  579. log.info("eqb请求入参,url:{},filePath:{},body:{},header:{}",url,filePath,body,header);
  580. String resultStr = HTTPHelper.uploadFile(url, "file", filePath, body, header, "UTF-8");
  581. log.info("eqb请求响应:{}",resultStr);
  582. Map result = (Map) JSONObject.parse(resultStr);
  583. isSuccess(result);
  584. Map data = UtilMap.getMap(result, "data");
  585. return data;
  586. }catch (Exception e){
  587. throw new RuntimeException();
  588. }
  589. }
  590. /**
  591. * hmac-sha256签名
  592. *
  593. * @param content 代签名的内容
  594. * @param key 签名的key
  595. * @return 签名
  596. */
  597. private String sign(String content, String key) {
  598. byte[] bytes = new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key).hmac(content);
  599. return new String(Hex.encodeHex(bytes));
  600. }
  601. //判断e签宝接口返回是否成功
  602. private void isSuccess(Map result){
  603. int code = UtilMap.getInt(result, "code");
  604. String message = UtilMap.getString(result, "message");
  605. if (200 != code || !"成功".equals(message)){
  606. throw new RuntimeException(message);
  607. }
  608. }
  609. }