TbServiceImpl.java 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824
  1. package com.malk.tuosi.service.impl;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONArray;
  4. import com.alibaba.fastjson.JSONObject;
  5. import com.fasterxml.jackson.core.JsonProcessingException;
  6. import com.fasterxml.jackson.core.type.TypeReference;
  7. import com.fasterxml.jackson.databind.JsonNode;
  8. import com.fasterxml.jackson.databind.ObjectMapper;
  9. import com.malk.server.common.McException;
  10. import com.malk.server.common.McR;
  11. import com.malk.server.common.VenR;
  12. import com.malk.server.dingtalk.DDConf;
  13. import com.malk.server.dingtalk.DDR_New;
  14. import com.malk.service.dingtalk.DDClient;
  15. import com.malk.service.dingtalk.DDClient_Extension;
  16. import com.malk.tuosi.service.TBService;
  17. import com.malk.utils.UtilHttp;
  18. import com.malk.utils.UtilMap;
  19. import com.sun.crypto.provider.PBEWithMD5AndDESCipher;
  20. import lombok.SneakyThrows;
  21. import lombok.extern.slf4j.Slf4j;
  22. import lombok.var;
  23. import org.springframework.beans.factory.annotation.Autowired;
  24. import org.springframework.stereotype.Service;
  25. import org.springframework.web.bind.annotation.RequestBody;
  26. import java.io.*;
  27. import java.net.*;
  28. import java.text.SimpleDateFormat;
  29. import java.time.LocalDateTime;
  30. import java.time.format.DateTimeFormatter;
  31. import java.util.*;
  32. import java.net.URL;
  33. import java.util.stream.Collectors;
  34. @Slf4j
  35. @Service
  36. public class TbServiceImpl implements TBService {
  37. /*TODO:TB获取应用token*/
  38. @Override
  39. public McR AppAccessToken() throws JsonProcessingException {
  40. HashMap body = new HashMap();
  41. body.put("appId","6874ba11d22c73565fd8af9d");
  42. body.put("appSecret","4JBgPwpctG27SuZrVVeCrXoiVCjie9ID");
  43. String doPost = UtilHttp.doPost("https://open.teambition.com/api/appToken",null,null,body);
  44. // 使用 Fastjson 解析 JSON
  45. JSONObject jsonObject = JSONObject.parseObject(doPost);
  46. String appToken = jsonObject.getString("appToken");
  47. log.info("Toke:{}",appToken);
  48. return McR.success(appToken);
  49. }
  50. /*TODO:钉钉获取应用token(欧诺架构)*/
  51. public McR Accesstoken() throws JsonProcessingException{
  52. HashMap params = new HashMap();
  53. params.put("appkey","dingtjgevp4t9vnlmpbj");
  54. params.put("appsecret","Q3CzrNIj4HjON8buv4zClgpf-A0cW5uDRB5UtMHJHAHuQDj-g1nmq-h7EeYe_i5a");
  55. String doGet = UtilHttp.doGet("https://oapi.dingtalk.com/gettoken", null, params);
  56. JSONObject jsonObject = JSONObject.parseObject(doGet);
  57. String accessToken = jsonObject.getString("access_token");
  58. log.info("accessToken:{}",accessToken);
  59. return McR.success(accessToken);
  60. }
  61. /*TODO:钉钉获取应用token(欧诺信架构)*/
  62. @Override
  63. public McR OuNuoXinAccessToken() throws JsonProcessingException {
  64. HashMap params = new HashMap();
  65. params.put("appkey","dingi61ncsi1zjo7eosp");
  66. params.put("appsecret","unvpxWgDeYEokuUlD-4iyDh0NdRH3NRKE1OkDF8VPQwyYi0Nuo_uXTWBYxnKYJaI");
  67. String doGet = UtilHttp.doGet("https://oapi.dingtalk.com/gettoken", null, params);
  68. JSONObject jsonObject = JSONObject.parseObject(doGet);
  69. String accessToken = jsonObject.getString("access_token");
  70. log.info("accessToken:{}",accessToken);
  71. return McR.success(accessToken);
  72. }
  73. /*TODO:接收TB推送的数据*/
  74. @SneakyThrows
  75. @Override
  76. public McR tbTaskUpdate(Map body) throws JsonProcessingException {
  77. String s = JSON.toJSONString(body);
  78. JSONObject jsonObject = JSON.parseObject(s);
  79. String event = jsonObject.getString("event");
  80. //一层过滤:过滤事件[任务自定义字段更新事件]
  81. if (event.equals("v3.task.customfield.update")){
  82. JSONObject data = jsonObject.getJSONObject("data");
  83. System.out.println(data);
  84. //二层过滤:过滤任务字段[只允许work类型字段类型生效]】
  85. String customfieldId = data.getString("customfieldId");//自定义字段ID
  86. // 1、版线组附件:6889f02fc74205217edfa65b 2、3D效果图:689d9834591915184b095e5f 3、白盒视频:6889c49443cbd3a23c9dc55f
  87. //todo:版线组附件回传CRM
  88. if(customfieldId.equals("6889f02fc74205217edfa65b") && data.getString("customfieldOldValue").equals("[]")){
  89. log.info("第一次上传,版线组附件为空");
  90. tbCallbackCRM(data);
  91. }
  92. String customfieldType = data.getString("customfieldType");//自定义字段类型
  93. String taskId = data.getString("taskId");//任务id
  94. if(customfieldType.equals("work")){
  95. /*TODO:查询任务详情,字段值,获取metaString*/
  96. HashMap head = new HashMap();
  97. McR accessToken = AppAccessToken();
  98. Object tokenData = accessToken.getData();
  99. head.put("Authorization","Bearer " + tokenData);
  100. head.put("X-Tenant-Id","61a8c26719c3b5ffe9c4cffb");
  101. head.put("X-Tenant-Type","organization");
  102. HashMap param = new HashMap();
  103. param.put("taskId",taskId);
  104. String doGet = UtilHttp.doGet("https://open.teambition.com/api/v3/task/query", head, param);//查询任务详情
  105. ObjectMapper objectMapper = new ObjectMapper();
  106. JsonNode rootNode = objectMapper.readTree(doGet);
  107. for(JsonNode resultNode : rootNode.path("result")){
  108. String content = resultNode.path("content").asText();//任务名称
  109. String customerName = "";//客户简称
  110. String manager = "";//节点负责人
  111. String designTime = "";//设计完成时间
  112. for(JsonNode customField : resultNode.path("customfields")) {
  113. String cfId = customField.path("cfId").asText();
  114. if ("68c23d6fee5aa63b8da58878".equals(cfId)) {
  115. JsonNode valueArray = customField.path("value");
  116. if (valueArray.isArray() && valueArray.size() > 0) {
  117. String dateTimeStr = valueArray.get(0).path("title").asText();
  118. // 解析UTC时间
  119. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
  120. sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
  121. Date date = sdf.parse(dateTimeStr);
  122. // 直接格式化为本地时间(不需要加8小时)
  123. SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
  124. designTime = outputFormat.format(date);
  125. }
  126. }
  127. }
  128. for(JsonNode customField : resultNode.path("customfields")){
  129. String cfId = customField.path("cfId").asText();
  130. if ("687df3b60ae1530fa2704499".equals(cfId)) {
  131. // 获取 value 数组中的第一个元素的 title
  132. JsonNode valueArray = customField.path("value");
  133. if (valueArray.isArray() && valueArray.size() > 0) {
  134. customerName = valueArray.get(0).path("title").asText();//客户简称
  135. }
  136. }else if ("66bb1a56f7e230ed6843796e".equals(cfId)){
  137. JsonNode valueArray = customField.path("value");
  138. if (valueArray.isArray() && valueArray.size() > 0) {
  139. manager = valueArray.get(0).path("title").asText();//节点负责人
  140. }
  141. } else if ("68c23d6fee5aa63b8da58878".equals(cfId)) {
  142. JsonNode valueArray = customField.path("value");
  143. if (valueArray.isArray() && valueArray.size() > 0) {
  144. String dateTimeStr = valueArray.get(0).path("title").asText();
  145. // 解析UTC时间
  146. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
  147. sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
  148. Date date = sdf.parse(dateTimeStr);
  149. // 加上8小时(转换为北京时间)
  150. Calendar calendar = Calendar.getInstance();
  151. calendar.setTime(date);
  152. calendar.add(Calendar.HOUR_OF_DAY, 8);
  153. // 格式化为 "yyyy-MM-dd HH:mm"
  154. SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
  155. designTime = outputFormat.format(calendar.getTime());//设计完成时间
  156. }
  157. }
  158. if(customfieldId.equals(cfId)){
  159. String writeValueAsString = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(customField);
  160. //解析metaString中的resourceId(附件可能会上传多个,所以得遍历customfield里面的值)
  161. ObjectMapper mapper = new ObjectMapper();
  162. JsonNode node = mapper.readTree(writeValueAsString);
  163. JsonNode valueArray = node.path("value");
  164. //检查value数组是否存在&不为空
  165. if(valueArray.isArray() && valueArray.size() > 0){
  166. List<String> allResourceIds = new ArrayList<>();
  167. List<String> allFileNames = new ArrayList<>();
  168. //遍历所有的value节点,收集resourceId和文件名title
  169. String resourceId = "";
  170. for (int i=0;i<valueArray.size();i++){
  171. JsonNode valueNode = valueArray.get(i);
  172. String metaString = valueNode.path("metaString").asText();
  173. String title = valueNode.path("title").asText();
  174. JsonNode metaJson = objectMapper.readTree(metaString);
  175. resourceId = metaJson.path("resourceId").asText();
  176. allResourceIds.add(resourceId);
  177. allFileNames.add(title);
  178. }
  179. if(!allResourceIds.isEmpty()){
  180. //根据resourceId获取文件详情 POST https://open.teambition.com/api/v3/file/query/by-resource-ids
  181. HashMap haader = new HashMap();
  182. haader.put("Content-Type", "application/json");
  183. haader.put("Authorization", "Bearer " + tokenData);
  184. haader.put("x-operator-id", "622ee3450cf3bb5e1a486f1f");
  185. haader.put("X-Tenant-Id", "61a8c26719c3b5ffe9c4cffb");
  186. haader.put("X-Tenant-Type", "organization");
  187. HashMap boody = new HashMap();
  188. boody.put("resourceIds",allResourceIds);
  189. boody.put("needSign",true);
  190. String fileDownloadResponse = UtilHttp.doPost("https://open.teambition.com/api/v3/file/query/by-resource-ids", haader, null, boody);
  191. JSONObject response = JSON.parseObject(fileDownloadResponse);
  192. JSONArray resultArray = response.getJSONArray("result");
  193. if(resultArray != null && resultArray.size() > 0){
  194. //todo:3D效果图放在新图案 白盒视频放在白盒库
  195. String basedir = "";
  196. String fileType = "";//附件类型:新图案(199256463063)、白盒(199256765924)
  197. if(customfieldId.equals("689d9834591915184b095e5f")){
  198. basedir = "C:/downloads/附件存储/新图案";
  199. fileType = "199256463063";
  200. }else if(customfieldId.equals("6889c49443cbd3a23c9dc55f")){
  201. basedir = "C:/downloads/附件存储/白盒库";
  202. fileType = "199256765924";
  203. }else {
  204. basedir = "C:/downloads/附件存储/其它";
  205. }
  206. List<String> successDownloads = new ArrayList<>();
  207. List<String> failedDownloads = new ArrayList<>();
  208. //遍历所有结果,下载每个文件(只需要拿到最新的内容即可)
  209. for (int i=0;i< resultArray.size();i++) {
  210. JSONObject fileObject = resultArray.getJSONObject(i);
  211. String downloadUrl = fileObject.getString("downloadUrl");
  212. //文件名称:设计完成时间-任务名称-客户简称-节点负责人-附件名称
  213. String fileName = designTime + "_" + content + "_" + customerName + "_" + manager + "_" + fileObject.getString("fileName");
  214. try {
  215. String savePath = downloadFile(downloadUrl, basedir, fileName);
  216. successDownloads.add(fileName + "->" + savePath);
  217. System.out.println("[文件本地存储成功][" + i + "]=====>" + fileName + "保存路径:" + savePath);
  218. /*TODO:钉盘文件存储一份*/
  219. System.out.println("[开始上传文件到钉盘]");
  220. uploadKnowledge(savePath, fileName,fileType);
  221. } catch (IOException e) {
  222. failedDownloads.add(fileName + "->" + e.getMessage());
  223. System.out.println("[文件下载失败][" + i + "]=====>" + fileName + "错误信息:" + e.getMessage());
  224. }
  225. }
  226. }else {
  227. System.out.println("[警告]未找到任何文件下载信息");
  228. }
  229. }
  230. }
  231. }
  232. }
  233. }
  234. }
  235. } else if (event.equals("v3.task.create")) {
  236. JSONObject data = jsonObject.getJSONObject("data");
  237. String sfcId = data.getString("sfcId");
  238. if (sfcId.equals("6878b3c0669d175c3c6bc679") || sfcId.equals("6878b3ceb5ffcf500365d17a") || sfcId.equals("6878b3d8f40485da4c5f99a2")
  239. || sfcId.equals("6878b39a27ae5f3cac355fb9") || sfcId.equals("6878b3a4090e6872fd6b78c6") || sfcId.equals("6878b3ad9e17ac8a027c6d37")
  240. || sfcId.equals("68999dc2d1cb63e672e0b503") || sfcId.equals("68999dcf3071884859cacb87") || sfcId.equals("6878b3b60d49d89e7955726f")
  241. || sfcId.equals("68999dd990de390188d8bee6")){
  242. String taskId = data.getString("taskId");
  243. HashMap header = new HashMap();
  244. header.put("x-operator-id","622ee3450cf3bb5e1a486f1f");//xmy
  245. McR Token = AppAccessToken();
  246. Object token = Token.getData();
  247. header.put("Authorization","Bearer " + token);
  248. header.put("X-Tenant-type","organization");
  249. header.put("X-Tenant-Id","61a8c26719c3b5ffe9c4cffb");
  250. HashMap body_AAA = new HashMap();
  251. String nodeId = null;
  252. switch (sfcId){
  253. case "6878b3c0669d175c3c6bc679" :
  254. nodeId = "6875ba31ff8968791e009dad";
  255. break;
  256. case "6878b3ceb5ffcf500365d17a" :
  257. nodeId = "6875c12442b4476582041a90";
  258. break;
  259. case "6878b3d8f40485da4c5f99a2" :
  260. nodeId = "6875c736476bc6384b458cfa";
  261. break;
  262. case "6878b39a27ae5f3cac355fb9" :
  263. nodeId = "6875f3cf4b7eb5199098892c";
  264. break;
  265. case "6878b3a4090e6872fd6b78c6" :
  266. nodeId = "6875f5e40a12fb0d64feb1e2";
  267. break;
  268. case "6878b3ad9e17ac8a027c6d37" :
  269. nodeId = "6875f78e43d815a435aa9308";
  270. break;
  271. case "68999dc2d1cb63e672e0b503" :
  272. nodeId = "6880881feac3a8e8f6e3aead";
  273. break;
  274. case "68999dcf3071884859cacb87" :
  275. nodeId = "68808b96767bd365b1b7b6f5";
  276. break;
  277. case "6878b3b60d49d89e7955726f" :
  278. nodeId = "6874c857ad8265662925a6ae";
  279. break;
  280. case "68999dd990de390188d8bee6":
  281. nodeId = "6880912c9c778244636507f8";
  282. break;
  283. }
  284. body_AAA.put("nodeId",nodeId);
  285. String doPut = UtilHttp.doPut(
  286. "https://open.teambition.com/api/v3/task/" + taskId + "/node/complete",
  287. header,
  288. null,
  289. body_AAA);
  290. log.info("[创建任务自动更新确认流程]");
  291. }
  292. }else if (event.equals("v3.task.node.status.update")) {
  293. /*群卡片推送*/
  294. JSONObject data = jsonObject.getJSONObject("data");
  295. String nodeId = data.get("nodeId").toString();
  296. String taskId = data.get("taskId").toString();
  297. if(("6875f58cf512415e5944c64c".equals(nodeId) || "6878a073eaa6f6ff736a5575".equals(nodeId)) && data.get("status").equals("finish")){//主管确认(1) 6875f58cf512415e5944c64c 主管确认(2)6878a073eaa6f6ff736a5575
  298. /*设计单主管确认节点*/
  299. List<String> allResourceIds = new ArrayList<>();//存储文件的ids
  300. List<String> downloadUrls= new ArrayList<>();//存储文件下载地址(原来的)
  301. List<String> newdownloadUrls = new ArrayList<>();//卡片存储文件地址(新的)
  302. /*所有的字段信息定义*/
  303. String content = "";//todo:任务名称
  304. List<String> involveMembers = new ArrayList<>();//todo:负责人
  305. String businessManager = "";//todo:业务经理
  306. String businessPerson = "";//todo:业务人员
  307. String customerName = "";//todo:客户名称
  308. String downloadUrl = "";
  309. String valueAsString = "";//todo:文件下载地址(jsonString)
  310. HashMap head = new HashMap();
  311. McR accessToken = AppAccessToken();
  312. Object tokenData = accessToken.getData();
  313. head.put("Authorization","Bearer " + tokenData);
  314. head.put("X-Tenant-Id","61a8c26719c3b5ffe9c4cffb");
  315. head.put("X-Tenant-Type","organization");
  316. HashMap param = new HashMap();
  317. param.put("taskId",taskId);
  318. String doGet = UtilHttp.doGet("https://open.teambition.com/api/v3/task/query", head, param);//查询任务详情
  319. ObjectMapper objectMapper = new ObjectMapper();
  320. JsonNode rootNode = objectMapper.readTree(doGet);
  321. JsonNode result = rootNode.path("result");
  322. for(JsonNode resultNode : rootNode.path("result")){
  323. content = resultNode.path("content").asText();//todo:任务名称
  324. JsonNode customFields = resultNode.path("customfields");
  325. if (customFields.isArray()) {
  326. for (JsonNode field : customFields) {
  327. String cfId = field.path("cfId").asText();
  328. // 检查是否有 value 数组
  329. JsonNode valueArray = field.path("value");
  330. if (!valueArray.isArray() || valueArray.size() == 0) {
  331. continue;
  332. }
  333. // 获取第一个 value 对象
  334. JsonNode firstValue = valueArray.get(0);
  335. switch (cfId) {
  336. case "687df458b9c2f9f90865c13b": // todo:业务经理
  337. businessManager = firstValue.path("title").asText();
  338. System.out.println("业务经理: " + businessManager);
  339. break;
  340. case "688191972ab6c4f412ea2bb9": // todo:业务人员
  341. businessPerson = firstValue.path("title").asText();
  342. System.out.println("业务人员: " + businessPerson);
  343. break;
  344. case "687df3b60ae1530fa2704499": // todo:客户名称
  345. customerName = firstValue.path("title").asText();
  346. System.out.println("客户名称: " + customerName);
  347. break;
  348. case "689d9834591915184b095e5f": // todo:附件 metaString
  349. JsonNode valueArray1 = field.path("value");
  350. if (valueArray1.isArray()) {
  351. for (JsonNode attachment : valueArray) {
  352. String metaString = attachment.path("metaString").asText();
  353. String title = attachment.path("title").asText();
  354. String director = title.substring(title.lastIndexOf("-") + 1, title.lastIndexOf("."));
  355. involveMembers.add(director);
  356. if (!metaString.isEmpty()) {
  357. ObjectMapper mapper = new ObjectMapper();
  358. JsonNode metaJson = mapper.readTree(metaString);
  359. String resourceId = metaJson.path("resourceId").asText();
  360. allResourceIds.add(resourceId);
  361. }
  362. }
  363. }
  364. HashMap haader = new HashMap();
  365. haader.put("Content-Type", "application/json");
  366. haader.put("Authorization", "Bearer " + tokenData);
  367. haader.put("x-operator-id", "622ee3450cf3bb5e1a486f1f");
  368. haader.put("X-Tenant-Id", "61a8c26719c3b5ffe9c4cffb");
  369. haader.put("X-Tenant-Type", "organization");
  370. HashMap boody = new HashMap();
  371. boody.put("resourceIds",allResourceIds);
  372. boody.put("needSign",true);
  373. String fileDownloadResponse = UtilHttp.doPost("https://open.teambition.com/api/v3/file/query/by-resource-ids", haader, null, boody);
  374. JSONObject response = JSON.parseObject(fileDownloadResponse);
  375. JSONArray resultArray = response.getJSONArray("result");
  376. for (int i=0;i< resultArray.size();i++) {
  377. JSONObject fileObject = resultArray.getJSONObject(i);
  378. downloadUrl = fileObject.getString("downloadUrl");
  379. downloadUrls.add(downloadUrl);
  380. }
  381. System.out.println("下载地址" + downloadUrls);//原下载地址
  382. //todo:把照片存在file目录下
  383. if(resultArray != null && resultArray.size()>0){
  384. String basedir = "file";
  385. ArrayList successDownloads = new ArrayList();
  386. ArrayList faileDownloads = new ArrayList();
  387. for (int i=0;i<resultArray.size();i++){
  388. JSONObject fileObject = resultArray.getJSONObject(i);//新下载地址
  389. String downloadUrl1 = fileObject.getString("downloadUrl");
  390. long millisTimestamp = System.currentTimeMillis();//当前时间戳
  391. String fileName = millisTimestamp + "_" + fileObject.getString("fileName");
  392. try{
  393. String savePath = downloadFile(downloadUrl1,basedir,fileName);//TODO;存储图片至file目录下
  394. successDownloads.add(fileName + "->" + savePath);
  395. System.out.println("文件存储成功["+i+"]=====>"+fileName+"保存路径:"+savePath);
  396. String newsavepath = "http://ounuo.raresoft.net:7880/file/"+fileName;
  397. newdownloadUrls.add(newsavepath);
  398. }catch (IOException e){
  399. faileDownloads.add(fileName+"->"+e.getMessage());
  400. System.out.println("文件下载失败["+i+"]=====>"+fileName+"错误信息:"+e.getMessage());
  401. }
  402. }
  403. }
  404. ObjectMapper mapper = new ObjectMapper();
  405. // 使用Stream API创建List<Map<String, String>>
  406. List<Map<String, String>> res = newdownloadUrls.stream()
  407. .map(url -> {
  408. Map<String, String> map = new LinkedHashMap<>(); // 保持顺序
  409. map.put("arr", url);
  410. return map;
  411. })
  412. .collect(Collectors.toList());
  413. valueAsString = mapper.writeValueAsString(res);
  414. System.out.println("格式化后的下载地址:" + valueAsString);
  415. break;
  416. }
  417. }
  418. }
  419. System.out.println(); // 空行分隔
  420. }
  421. //组装数据卡片推送
  422. // 业务经理=宁学刚推送至“郝总—节令—设计对接”cid2niI2sTPksK5PHpfrLgCPQ== 业务经理=姜华推送至“姜华—流通—设计对接”cid+J9H07847VNwIYiLpNay0Q== 业务经理=谷晨丹推送至“谷晨丹—烘焙—设计对接”cidqXtqGAN+Es7L/5m3uaZzSg== 业务经理=赵宇娟推送至"赵宇娟—烘焙—设计对接"cidaUtMTIjDHM60UXFfHegKtg==
  423. JSONObject cardData = new JSONObject();
  424. cardData.put("name_task", content);
  425. cardData.put("designer", String.join(",", involveMembers));
  426. cardData.put("name_person", businessManager + "," + businessPerson);
  427. cardData.put("name_customer", customerName);
  428. cardData.put("arr_picture", valueAsString);//todo:里面的每个需要转成jsonString类型
  429. cardData.put("link","https://www.teambition.com/project/6878b323386fac7ab9dbe5e9/tasks/view/6878b323cc336006f34d1d22/task/"+taskId);
  430. JSONObject message = new JSONObject();
  431. message.put("cardData", cardData);
  432. message.put("outTrackId", String.valueOf(System.currentTimeMillis()));
  433. if("宁学刚".equals(businessManager)){
  434. message.put("openSpaceId", "dtv1.card//IM_GROUP.cid2niI2sTPksK5PHpfrLgCPQ==");
  435. } else if ("姜华".equals(businessManager)) {
  436. message.put("openSpaceId", "dtv1.card//IM_GROUP.cid+J9H07847VNwIYiLpNay0Q==");
  437. }else if ("赵宇娟".equals(businessManager)) {
  438. message.put("openSpaceId", "dtv1.card//IM_GROUP.cidaUtMTIjDHM60UXFfHegKtg==");
  439. } else if ("陈晶".equals(businessManager) || "郝俊秀".equals(businessManager) || "鲁萍".equals(businessManager)) {
  440. message.put("openSpaceId", "dtv1.card//IM_GROUP.cidTppONwRCrkshRlCt28O+NA==");
  441. }else if ("张曼".equals(businessManager)){
  442. message.put("openSpaceId","dtv1.card//IM_GROUP.cidXES2AIusSs+mb9gD8i4w1w==");
  443. }else if("张昆".equals(businessManager)){
  444. message.put("openSpaceId","dtv1.card//IM_GROUP.cidI3G/EnCvlem5w3+qKfTMDA==");
  445. }
  446. // message.put("openSpaceId", "dtv1.card//IM_GROUP.cidTppONwRCrkshRlCt28O+NA==");//正式群id:cidTppONwRCrkshRlCt28O+NA== 测试群id:cidKoVDKhvynnj+73h0uxSJBA==
  447. message.put("cardTemplateId", "160b26bf-d699-49fc-a6dc-9cd20eed7750.schema");
  448. message.put("robotCode", "dinghhozexm92tupobfo");
  449. // message.put("link","https://www.teambition.com/project/6878b323386fac7ab9dbe5e9/tasks/view/6878b323cc336006f34d1d22/task/" + taskId);
  450. createAndDeliverCard(message);//调用卡片推送
  451. }
  452. }
  453. return McR.success();
  454. }
  455. /*TODO:钉盘文件上传*/
  456. @SneakyThrows
  457. @Override
  458. public McR uploadKnowledge(String pathName,String fileName,String fileType) throws JsonProcessingException {
  459. /*TODO:step1:获取上传文件需要的resourceUrls和headers参数值*/
  460. HashMap head = new HashMap();
  461. McR accessToken = Accesstoken();
  462. Object tokenData = accessToken.getData();
  463. head.put("x-acs-dingtalk-access-token",tokenData);
  464. HashMap params = new HashMap();
  465. params.put("unionId","Vwt6seFpRYYCh1yj2BBTCwiEiE");
  466. HashMap body = new HashMap();
  467. body.put("protocol","HEADER_SIGNATURE");//默认
  468. body.put("multipart",false);//5G以下文件,设为false
  469. DDR_New deptDDR = (DDR_New) UtilHttp.doPost("https://api.dingtalk.com/v1.0/storage/spaces/27116552652/files/uploadInfos/query", head, params, body, DDR_New.class);
  470. Map headerSignatureInfo = deptDDR.getHeaderSignatureInfo();
  471. /*TODO:step2:使用OSS的header加签方式上传文件*/
  472. List<String> resourceUrls = (List<String>) headerSignatureInfo.get("resourceUrls");
  473. //从接口中获取到resourceUrl
  474. String resourceUrl = resourceUrls.get(0);
  475. //从接口中获取到headers
  476. Map<String, String> headers = (Map<String, String>) headerSignatureInfo.get("headers");
  477. URL url = new URL(resourceUrl);
  478. HttpURLConnection connection = (HttpURLConnection)url.openConnection();
  479. if (headers != null) {
  480. for (Map.Entry<String, String> entry : headers.entrySet()) {
  481. connection.setRequestProperty(entry.getKey(), entry.getValue());
  482. }
  483. }
  484. connection.setDoOutput(true);
  485. connection.setRequestMethod("PUT");
  486. connection.setUseCaches(false);
  487. connection.setReadTimeout(10000);
  488. connection.setConnectTimeout(10000);
  489. connection.connect();
  490. OutputStream out = connection.getOutputStream();
  491. InputStream is = new FileInputStream(new File(pathName));
  492. byte[] b =new byte[1024];
  493. int temp;
  494. while ((temp=is.read(b))!=-1){
  495. out.write(b,0,temp);
  496. }
  497. out.flush();
  498. out.close();
  499. int responseCode = connection.getResponseCode();
  500. connection.disconnect();
  501. if (responseCode == 200) {
  502. System.out.println("上传成功");
  503. } else {
  504. System.out.println("上传失败");
  505. }
  506. /*TODO:step3:调用提交文件接口,完成文件上传*/
  507. HashMap param = new HashMap();
  508. param.put("unionId","Vwt6seFpRYYCh1yj2BBTCwiEiE");
  509. HashMap boddy = new HashMap();
  510. String uploadKey = deptDDR.getUploadKey();
  511. boddy.put("uploadKey",uploadKey);//添加文件唯一标识uploadKey
  512. boddy.put("name",fileName);//文件的名称,带后缀
  513. boddy.put("parentId",fileType);//父目录Id====> 白盒库:199256765924 新图案:199256463063
  514. HashMap header = new HashMap();
  515. header.put("x-acs-dingtalk-access-token",tokenData);
  516. String post = UtilHttp.doPost("https://api.dingtalk.com/v1.0/storage/spaces/27116552652/files/commit", header, param, boddy);
  517. return McR.success(post);
  518. }
  519. /*TODO:版线组位置附件上传CRM*/
  520. @Override
  521. public McR tbCallbackCRM(Map body) throws JsonProcessingException {
  522. String s = JSON.toJSONString(body);
  523. //解析参数拿到taskIda
  524. JSONObject object = JSON.parseObject(s);
  525. String taskId = object.getString("taskId");//任务id
  526. String customfieldId = object.getString("customfieldId");//自定义字段id
  527. //获取回传CRM中的crmid metaString(若有)
  528. HashMap head = new HashMap();
  529. McR accessToken = AppAccessToken();
  530. Object tokenData = accessToken.getData();
  531. head.put("Authorization","Bearer " + tokenData);
  532. head.put("X-Tenant-Id","61a8c26719c3b5ffe9c4cffb");
  533. head.put("X-Tenant-Type","organization");
  534. HashMap param = new HashMap();
  535. param.put("taskId",taskId);
  536. String doGet = UtilHttp.doGet("https://open.teambition.com/api/v3/task/query", head, param);
  537. JSONObject responseJson = JSON.parseObject(doGet);
  538. JSONArray resultArray = responseJson.getJSONArray("result");
  539. String crmid = null;
  540. String metaString = null;
  541. String resourceId = null;
  542. List<String> resourceIds_AAA = new ArrayList<>();
  543. if(resultArray != null && !resultArray.isEmpty()){
  544. JSONObject task = resultArray.getJSONObject(0);
  545. JSONArray customFields = task.getJSONArray("customfields");
  546. if(customFields != null){
  547. for (int i = 0; i < customFields.size(); i++) {
  548. JSONObject field = customFields.getJSONObject(i);
  549. String cfId = field.getString("cfId");
  550. if("689d4ebf343c05fe73700c93".equals(cfId)){//CRM单据ID
  551. JSONArray valueArray = field.getJSONArray("value");
  552. if(valueArray != null && !valueArray.isEmpty()){
  553. JSONObject firstValue = valueArray.getJSONObject(0);
  554. crmid = firstValue.getString("title");
  555. }
  556. }
  557. if("6889f02fc74205217edfa65b".equals(cfId)){//版线位置附件
  558. JSONArray array = field.getJSONArray("value");
  559. if(array != null && !array.isEmpty()){
  560. for (int j = 0; j < array.size(); j++) {
  561. JSONObject firstValue1 = array.getJSONObject(j);
  562. metaString =firstValue1.getString("metaString");
  563. JSONObject jsonObject = JSON.parseObject(metaString);
  564. resourceId = jsonObject.getString("resourceId");
  565. }
  566. resourceIds_AAA.add(resourceId);
  567. }
  568. }
  569. }
  570. }
  571. }
  572. //获取当前变更时间 202x-0x-xx xx:xx:xx
  573. LocalDateTime now = LocalDateTime.now();
  574. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  575. String jssj = now.format(formatter);
  576. //获取文件downloadurl(若有) 1、查询任务详情(拿到metaString) 2、获取文件下载URL
  577. String done = null;
  578. if(!metaString.isEmpty()){
  579. HashMap header = new HashMap();
  580. McR Token = AppAccessToken();
  581. Object token = Token.getData();
  582. header.put("Authorization","Bearer " + token);
  583. header.put("X-Tenant-Id","61a8c26719c3b5ffe9c4cffb");
  584. header.put("X-Tenant-Type","organization");
  585. HashMap bodyy = new HashMap();
  586. bodyy.put("needSign",true);
  587. bodyy.put("resourceIds",resourceIds_AAA);
  588. String post = UtilHttp.doPost("https://open.teambition.com/api/v3/file/query/by-resource-ids", header, null, bodyy);
  589. String downloadURL = JSON.parseObject(post).getJSONArray("result").getJSONObject(0).getString("downloadUrl");
  590. //获取文件名称
  591. String fileName = JSON.parseObject(post).getJSONArray("result").getJSONObject(0).getString("fileName");
  592. //TODO:调用TB回传CRM接口
  593. //构建请求头
  594. HashMap headers = new HashMap();
  595. headers.put("crmuserid","620131c2fe8d7eb6b8dfbf76");//tb的userid(固定是张昆)
  596. headers.put("TargetSystem","CRM");//固定值
  597. //构建params参数
  598. HashMap params = new HashMap();
  599. params.put("crmid",crmid);
  600. params.put("jssj",jssj);
  601. params.put("bxwz",downloadURL);
  602. params.put("bxwzsname",fileName);
  603. //构建body参数
  604. HashMap bodys = new HashMap();
  605. bodys.put("params",params);
  606. done = UtilHttp.doPost("http://ounuo.ip.raresoft.net:8888/api/dd/selfchange", headers, null, bodys);
  607. }
  608. return McR.success(done);
  609. }
  610. @Autowired
  611. private DDConf ddConf;
  612. @Autowired
  613. private DDClient ddClient;
  614. @Override
  615. public McR oaCallbackTB(Map body) throws JsonProcessingException {
  616. //获取单个审批实例详情
  617. HashMap params_AAA = new HashMap();
  618. params_AAA.put("appkey","dingi61ncsi1zjo7eosp");
  619. params_AAA.put("appsecret","unvpxWgDeYEokuUlD-4iyDh0NdRH3NRKE1OkDF8VPQwyYi0Nuo_uXTWBYxnKYJaI");
  620. String doGet = UtilHttp.doGet("https://oapi.dingtalk.com/gettoken", null, params_AAA);
  621. JSONObject jsonObject_AAA = JSONObject.parseObject(doGet);
  622. String accessToken = jsonObject_AAA.getString("access_token");
  623. HashMap head_AAA = new HashMap();
  624. head_AAA.put("x-acs-dingtalk-access-token",accessToken);
  625. HashMap params = new HashMap();
  626. String InstanceId = body.get("InstanceId").toString();
  627. params.put("processInstanceId",InstanceId);
  628. String s = UtilHttp.doGet("https://api.dingtalk.com/v1.0/workflow/processInstances", head_AAA, params);
  629. JSONObject jsonObject = JSON.parseObject(s);
  630. JSONObject jsonObject1 = jsonObject.getJSONObject("result");
  631. JSONArray jsonArray = jsonObject1.getJSONArray("operationRecords");
  632. String remark = "";
  633. for (int i = 0; i < jsonArray.size(); i++) {
  634. JSONObject jsonObject2 = jsonArray.getJSONObject(i);
  635. String type = jsonObject2.getString("type");
  636. String s1 = jsonObject2.getString("remark");
  637. if (type.equals("ADD_REMARK") && s1.contains("发起审批的 Teambition 任务")){
  638. remark = jsonObject2.getString("remark");
  639. }
  640. }
  641. //截取remark中()的内容
  642. String remarkStr111 = remark.substring(remark.indexOf("(") + 1, remark.indexOf(")"));
  643. String remarkStr222 = "";
  644. try {
  645. remarkStr222 = URLDecoder.decode(remarkStr111, "UTF-8");
  646. }catch (Exception e){
  647. e.printStackTrace();
  648. }
  649. String remarkStr333 = "";
  650. try {
  651. remarkStr333 = URLDecoder.decode(remarkStr222, "UTF-8");
  652. }catch (Exception e){
  653. e.printStackTrace();
  654. }
  655. //获取链接中的tasks/后?前的参数
  656. String strStart = "tasks/";
  657. String endStart = "?isDingtalkHeaderHidden";
  658. String taskId = remarkStr333.substring(remarkStr333.indexOf(strStart) + 6, remarkStr333.lastIndexOf(endStart));
  659. //更新任务
  660. double value = 0;
  661. String name = "";
  662. JSONArray array = jsonObject1.getJSONArray("formComponentValues");
  663. for (int j=0;j<array.size();j++){
  664. JSONObject object = array.getJSONObject(j);
  665. name = object.getString("name");
  666. if(name.equals("版费总价")){
  667. value = object.getDoubleValue("value");
  668. }
  669. }
  670. HashMap head = new HashMap();
  671. head.put("x-operator-id","622ee3450cf3bb5e1a486f1f");
  672. McR Token = AppAccessToken();
  673. Object tok = Token.getData();
  674. head.put("Authorization","Bearer " + tok);
  675. head.put("X-Tenant-type","organization");
  676. head.put("X-Tenant-Id","61a8c26719c3b5ffe9c4cffb");
  677. String finalName = name;
  678. double finalValue = value;
  679. HashMap<String,Object> bodyy = new HashMap<String,Object>(){{
  680. put("customfieldName", finalName);
  681. put("value",Collections.singletonList(
  682. new HashMap<String,String>() {{
  683. put("title", String.valueOf(finalValue));
  684. }}
  685. ));
  686. }};
  687. String s1 = UtilHttp.doPost("https://open.teambition.com/api/v3/task/" + taskId + "/customfield/update", head, null, bodyy);
  688. return McR.success(s1);
  689. }
  690. @Override
  691. public String TBtoDinguserId(List list) throws JsonProcessingException {
  692. System.out.println(list);
  693. HashMap header = new HashMap();
  694. McR accessToken = AppAccessToken();
  695. Object tokenData = accessToken.getData();
  696. header.put("Authorization","Bearer " + tokenData);
  697. header.put("X-Tenant-type","organization");
  698. header.put("X-Tenant-Id","61a8c26719c3b5ffe9c4cffb");
  699. HashMap param = new HashMap();
  700. param.put("tbUserIds",list);
  701. String s = UtilHttp.doGet("https://open.teambition.com/api/idmap/dingtalk/getDingUserId", header, param);
  702. ObjectMapper objectMapper = new ObjectMapper();
  703. var rootNode = objectMapper.readTree(s);
  704. List<String> userIdList = objectMapper.convertValue(
  705. rootNode.get("result"),
  706. new TypeReference<List<Map<String, String>>>() {
  707. }
  708. )
  709. .stream()
  710. .map(map -> map.get("dingtalkUserId"))
  711. .collect(Collectors.toList());
  712. //开始处理userid查询用户名称
  713. HashMap params = new HashMap();
  714. McR Token = OuNuoXinAccessToken();
  715. Object Data = Token.getData();
  716. params.put("access_token",Data);
  717. HashMap body = new HashMap();
  718. List<String> nameList = new ArrayList<>();
  719. String result = "";
  720. for (String str : userIdList){
  721. body.put("userid",str);
  722. String doPost = UtilHttp.doPost("https://oapi.dingtalk.com/topapi/v2/user/get", null, params, body);
  723. ObjectMapper objectmapper = new ObjectMapper();
  724. String username = objectMapper.readTree(doPost)
  725. .path("result")
  726. .path("name")
  727. .asText();
  728. nameList.add(username);
  729. result = nameList.stream()
  730. .collect(Collectors.joining(","));
  731. }
  732. return result;
  733. }
  734. //文件存储方法
  735. /**
  736. * 下载文件到本地(自定义文件名)
  737. * param fileUrl 文件下载URL
  738. * param baseDir 基础存储目录
  739. * param customFileName 自定义文件名(不含扩展名)
  740. * return 下载后的文件绝对路径
  741. */ public static String downloadFile(String fileUrl,String baseDir,String customFileName) throws IOException{
  742. // 创建基础目录
  743. File baseDirectory = new File(baseDir);
  744. if (!baseDirectory.exists()) {
  745. baseDirectory.mkdirs();
  746. }
  747. // 完整的保存路径
  748. String savePath = new File(baseDir, customFileName).getAbsolutePath();
  749. // 下载文件
  750. URL url = new URL(fileUrl);
  751. URLConnection connection = url.openConnection();
  752. try (InputStream in = connection.getInputStream();
  753. FileOutputStream out = new FileOutputStream(savePath)) {
  754. byte[] buffer = new byte[4096];
  755. int bytesRead;
  756. while ((bytesRead = in.read(buffer)) != -1) {
  757. out.write(buffer, 0, bytesRead);
  758. }
  759. }
  760. return savePath;
  761. }
  762. @Autowired
  763. private DDClient_Extension ddClientExtension;
  764. /*群消息卡片推送*/
  765. public McR createAndDeliverCard(@RequestBody JSONObject param){
  766. log.info("推送消息:{}",param);
  767. McException.assertParamException_Null(param,"cardData","outTrackId","openSpaceId","robotCode","cardTemplateId");
  768. Map<String,Object> data = new HashMap();
  769. data.put("imGroupOpenDeliverModel", UtilMap.map("robotCode",param.getString("robotCode")));
  770. data.put("imGroupOpenSpaceModel",UtilMap.map("supportForward",true));
  771. if(param.containsKey("extInfo")){
  772. data.putAll(param.getJSONObject("extInfo"));
  773. }
  774. Map map = ddClientExtension.createAndDeliverCards(ddClient.getAccessToken(),param.getString("cardTemplateId"),param.getString("outTrackId"),
  775. UtilMap.map("cardParamMap",param.getJSONObject("cardData")),param.getString("openSpaceId"),data);
  776. return McR.success(map);
  777. }
  778. }