PayServiceImpl.java 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  1. package com.malk.mankalong.service.Impl;
  2. import cn.hutool.core.date.DateUtil;
  3. import cn.hutool.core.util.ObjectUtil;
  4. import cn.hutool.http.HttpRequest;
  5. import cn.hutool.http.HttpResponse;
  6. import com.alibaba.fastjson.JSON;
  7. import com.alibaba.fastjson.JSONArray;
  8. import com.alibaba.fastjson.JSONObject;
  9. import com.malk.mankalong.service.PayService;
  10. import com.malk.server.aliwork.YDConf;
  11. import com.malk.server.aliwork.YDParam;
  12. import com.malk.server.common.McR;
  13. import com.malk.server.dingtalk.DDConf;
  14. import com.malk.server.dingtalk.DDR_New;
  15. import com.malk.service.aliwork.YDClient;
  16. import com.malk.service.aliwork.YDService;
  17. import com.malk.service.dingtalk.DDClient;
  18. import com.malk.service.dingtalk.DDClient_Personnel;
  19. import com.malk.service.dingtalk.DDClient_Workflow;
  20. import com.malk.service.dingtalk.DDService;
  21. import com.malk.utils.UtilFile;
  22. import com.malk.utils.UtilHttp;
  23. import com.malk.utils.UtilMap;
  24. import lombok.extern.slf4j.Slf4j;
  25. import org.springframework.beans.factory.annotation.Autowired;
  26. import org.springframework.beans.factory.annotation.Value;
  27. import org.springframework.stereotype.Service;
  28. import java.io.*;
  29. import java.lang.reflect.Field;
  30. import java.net.HttpURLConnection;
  31. import java.net.URL;
  32. import java.net.URLDecoder;
  33. import java.nio.charset.StandardCharsets;
  34. import java.sql.Array;
  35. import java.time.Instant;
  36. import java.time.LocalDateTime;
  37. import java.time.ZoneId;
  38. import java.time.format.DateTimeFormatter;
  39. import java.util.*;
  40. import java.util.concurrent.ConcurrentHashMap;
  41. @Service
  42. @Slf4j
  43. public class PayServiceImpl implements PayService {
  44. @Autowired
  45. private DDClient ddClient;
  46. @Autowired
  47. private DDClient_Workflow ddClient_workflow;
  48. @Autowired
  49. private DDClient_Personnel ddClientPersonnel;
  50. @Value(value = "${dingtalk.appKey}")
  51. private String APP_EKY;
  52. @Value(value = "${dingtalk.appSecret}")
  53. private String APP_SECRET;
  54. @Value(value = "${dingtalk.agentId}")
  55. private Long agentId;
  56. @Value(value = "${dingtalk.unionId}")
  57. private String unionId;
  58. @Value(value = "${dingtalk.spaceId}")
  59. private String spaceId;
  60. @Value(value = "${dingtalk.parentId}")
  61. private String parentId;
  62. @Value(value = "${saveFile.path}")
  63. private String saveFilePath;
  64. @Value(value = "${dingtalk.parentUuid}")
  65. private String parentDentryUuid;
  66. @Value("${aliwork.appType}")
  67. private String appType;
  68. @Value("${aliwork.systemToken}")
  69. private String systemToken;
  70. @Autowired
  71. private DDConf ddConf;
  72. @Autowired
  73. DDService ddService;
  74. @Autowired
  75. private YDService ydService;
  76. @Autowired
  77. private YDClient ydClient;
  78. private static final String API_TOKEN = "/common/unAuth/tokens/generate";
  79. private static final String POST_DATA_URL = "/common/document";
  80. private static final String FIND_BY_CODES = "/common/users/v2/findByCodes";
  81. private static final String FIND_COMPANY = "/common/departments/v2/findByCode";
  82. private ConcurrentHashMap<String, LocalDateTime> tokenStore = new ConcurrentHashMap<>();
  83. //出差类型枚举
  84. private static final Map<String, String> AMOUNT_TYPE = new HashMap<>();
  85. static {
  86. AMOUNT_TYPE.put("收款", "收入");
  87. AMOUNT_TYPE.put("付款", "支出");
  88. AMOUNT_TYPE.put("不结算", "无金额");
  89. AMOUNT_TYPE.put("收支双向", "无金额");
  90. }
  91. private static final Map<String, String> ATTACHMENT_ENUM = new HashMap<>();
  92. static {
  93. ATTACHMENT_ENUM.put("attachmentUrl","附件");
  94. ATTACHMENT_ENUM.put("contractTextUrl","合同正文");
  95. ATTACHMENT_ENUM.put("contractScanUrl","上传生效的合同扫描件");
  96. ATTACHMENT_ENUM.put("contractPreApprovalFlow","合同前置审批流程");
  97. ATTACHMENT_ENUM.put("procurementResult","oa请示、采购结果");
  98. ATTACHMENT_ENUM.put("decisionDocument","决策文件、会议纪要、中标通知书等");
  99. }
  100. //所有的枚举
  101. private static final Map<String, String> ALLENUM = new HashMap<>();
  102. static {
  103. //签署法人实体
  104. ALLENUM.put("option_aoscience_bio_nantong_co_l__c", "澳斯康生物(南通)股份有限公司");
  105. ALLENUM.put("option_gansu_jianshun_biotech_co__c", "甘肃健顺生物科技有限公司");
  106. ALLENUM.put("option_jianshun_bio_tech_nantong__c", "健顺生物科技(南通)有限公司");
  107. ALLENUM.put("option_shanghai_aoskang_bio_pharm__c", "上海澳斯康生物制药有限公司");
  108. }
  109. /**
  110. * 从Content-Disposition头获取文件名
  111. */
  112. private static String getFileNameFromConnection(HttpURLConnection connection) {
  113. String contentDisposition = connection.getHeaderField("Content-Disposition");
  114. if (contentDisposition != null) {
  115. // 查找filename=后面的内容
  116. String[] parts = contentDisposition.split(";");
  117. for (String part : parts) {
  118. if (part.trim().startsWith("filename=")) {
  119. String fileName = part.substring(part.indexOf('=') + 1).trim();
  120. // 去除引号并解码URL编码
  121. fileName = fileName.replace("\"", "");
  122. try {
  123. return URLDecoder.decode(fileName, StandardCharsets.UTF_8.name());
  124. } catch (UnsupportedEncodingException e) {
  125. return fileName;
  126. }
  127. }
  128. }
  129. }
  130. return null;
  131. }
  132. //下载宜搭附件
  133. private String downloadFile(String fileURL, String contractName, String type, String savePath) throws IOException {
  134. //若是宜搭附件url 则需获得附件临时免登地址
  135. // fileURL = ydClient.convertTemporaryUrl(fileURL);
  136. URL url = new URL(fileURL);
  137. HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
  138. httpConn.setRequestMethod("GET");
  139. httpConn.setInstanceFollowRedirects(true); // 强制跟随重定向(必加!)
  140. httpConn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");
  141. httpConn.setConnectTimeout(10000);
  142. httpConn.setReadTimeout(20000);
  143. httpConn.setDoInput(true);
  144. httpConn.setDoOutput(false);
  145. int responseCode = httpConn.getResponseCode();
  146. // 获取文件名
  147. // String fileName = getFileNameFromConnection(httpConn);
  148. String fileName = contractName + "." + type;
  149. // 检查HTTP响应代码是否为200
  150. if (responseCode == HttpURLConnection.HTTP_OK) {
  151. InputStream inputStream = httpConn.getInputStream();
  152. FileOutputStream outputStream = new FileOutputStream(savePath + fileName);
  153. byte[] buffer = new byte[8192];
  154. int bytesRead = -1;
  155. while ((bytesRead = inputStream.read(buffer)) != -1) {
  156. outputStream.write(buffer, 0, bytesRead);
  157. }
  158. outputStream.close();
  159. inputStream.close();
  160. } else {
  161. System.out.println("无法下载文件。HTTP响应代码: " + responseCode);
  162. }
  163. httpConn.disconnect();
  164. return fileName;
  165. }
  166. /**
  167. * 上传文件至钉盘
  168. * @param filePath 文件存储地址
  169. * @param conflictStrategy 覆盖或其他上传方式
  170. * @return
  171. */
  172. private Map uploadToDingTalk(String filePath,String conflictStrategy) {
  173. //获取当前时间戳
  174. long beginTimestamp = System.currentTimeMillis();
  175. System.out.println("开始上传附件:" + DateUtil.format(new Date(beginTimestamp), "yyyy-MM-dd HH:mm:ss"));
  176. //文件
  177. File file = new File(filePath);
  178. //获取文件上传信息
  179. Map param = new HashMap();
  180. param.put("unionId",unionId);
  181. Map body = new HashMap();
  182. body.put("protocol","HEADER_SIGNATURE");
  183. body.put("multipart",false);
  184. DDR_New ddr = (DDR_New) UtilHttp.doPost("https://api.dingtalk.com/v1.0/storage/spaces/" + spaceId + "/files/uploadInfos/query", ddConf.initTokenHeader(ddClient.getAccessToken()), param, body, DDR_New.class);
  185. String uploadKey = ddr.getUploadKey();
  186. Map headerSignatureInfo = ddr.getHeaderSignatureInfo();
  187. Map<String,String> headers = (Map<String,String>) headerSignatureInfo.get("headers");
  188. List<String> resourceUrls = (List<String>) headerSignatureInfo.get("resourceUrls");
  189. String resourceUrl = resourceUrls.get(0);
  190. Map dentry = new HashMap();
  191. //使用OSS的header加签方式上传文件
  192. try {
  193. URL url = new URL(resourceUrl);
  194. HttpURLConnection connection = (HttpURLConnection)url.openConnection();
  195. if (headers != null) {
  196. for (Map.Entry<String, String> entry : headers.entrySet()) {
  197. connection.setRequestProperty(entry.getKey(), entry.getValue());
  198. }
  199. }
  200. connection.setDoOutput(true);
  201. connection.setRequestMethod("PUT");
  202. connection.setUseCaches(false);
  203. connection.setReadTimeout(10000);
  204. connection.setConnectTimeout(10000);
  205. connection.connect();
  206. OutputStream out = connection.getOutputStream();
  207. InputStream is = new FileInputStream(file);
  208. byte[] b =new byte[1024];
  209. int temp;
  210. while ((temp=is.read(b))!=-1){
  211. out.write(b,0,temp);
  212. }
  213. out.flush();
  214. out.close();
  215. int responseCode = connection.getResponseCode();
  216. connection.disconnect();
  217. if (responseCode == 200) {
  218. System.out.println("上传成功");
  219. } else {
  220. System.out.println("上传失败");
  221. }
  222. //提交文件
  223. Map body2 = new HashMap();
  224. Map option = new HashMap();
  225. option.put("conflictStrategy",conflictStrategy);
  226. body2.put("uploadKey",uploadKey);
  227. body2.put("name",file.getName());
  228. body2.put("option",option);
  229. 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);
  230. dentry = ddrNew.getDentry();
  231. }catch (IOException e){
  232. log.info("上传文件异常:{}",e);
  233. }
  234. long endTimestamp = System.currentTimeMillis();
  235. System.out.println("上传文件结束:" + DateUtil.format(new Date(endTimestamp), "yyyy-MM-dd HH:mm:ss"));
  236. System.out.println("上传文件耗时:" + (endTimestamp - beginTimestamp)/1000.0 + "s");
  237. return dentry;
  238. }
  239. private Map<String, Object> convert(Object object) throws Exception {
  240. Map<String, Object> map = new HashMap<>();
  241. Class<?> clazz = object.getClass();
  242. for (Field field : clazz.getDeclaredFields()) {
  243. field.setAccessible(true);
  244. String value = field.get(object) != null ? field.get(object).toString() : "";
  245. map.put(field.getName(), value);
  246. }
  247. return map;
  248. }
  249. /**
  250. * 获取钉钉员工手机号
  251. * @param workingEmployeeIds 钉钉人员id
  252. * @return
  253. */
  254. public List<String> getDeptIdByUserId(List<String> workingEmployeeIds) {
  255. log.info("根据钉钉人员id获取员工部门id:{}",workingEmployeeIds.toString());
  256. List<String> filterList = new ArrayList<>();
  257. filterList.add("sys00-mainDeptId");
  258. List<Map> employeeInfos = ddClientPersonnel.getEmployeeInfos(ddClient.getAccessToken(), workingEmployeeIds, agentId, filterList);
  259. List<String> personList = new ArrayList<>();
  260. employeeInfos.forEach(e -> {
  261. List<Map> mapList = (List<Map>) e.get("field_data_list");
  262. mapList.forEach(m -> {
  263. List<Map> valueList = (List<Map>) m.get("field_value_list");
  264. String value = valueList.get(0).get("value").toString();
  265. personList.add(value);
  266. });
  267. });
  268. return personList;
  269. }
  270. private Map MATE;
  271. /**
  272. * 加载json
  273. */
  274. private Map _getMeta() {
  275. if (ObjectUtil.isNull(MATE)) {
  276. MATE = (Map) UtilFile.readJsonObjectFromResource("json/form.json"); // 本地匹配宜搭组件ID
  277. // MATE = (Map) UtilFile.readJsonObjectFromResource("static/json/formtest.json"); // 本地匹配宜搭组件ID
  278. }
  279. return MATE;
  280. }
  281. /**
  282. * 整合传参数据为OA审批 name - value 数据格式
  283. * @param code 单据类型
  284. * @param data 传参
  285. * @param meta json
  286. * @param formValue OA审批数据格式
  287. */
  288. private void IntegrationData(String code, Map data, Map meta, List<Map> formValue) {
  289. log.info("开始处理接口参数数据转为OA审批接口数据格式");
  290. //json数据列
  291. Map<String, ?> component = (Map) ((Map) meta.get(code)).get("compIds");
  292. for (String key : component.keySet()) {
  293. Map formData = UtilMap.empty();
  294. if (key.startsWith("tableField_")) {
  295. String[] split = key.split("_");
  296. List<Map> rows = UtilMap.getList(data,split[1]);
  297. List<List<Map>> lastList = new ArrayList<>();
  298. Map<String, String> compIds = (Map) component.get(key);
  299. if (rows.size() > 0 ){
  300. for (Map row : rows) {
  301. List<Map> details = new ArrayList<>();
  302. for (String prop : compIds.keySet()) {
  303. Map detail = UtilMap.empty();
  304. detail.put("value", row.get(compIds.get(prop)));
  305. detail.put("name", prop);
  306. if (prop.contains("我方主体名称")){
  307. detail.put("bizAlias","contract_mine_company_name");
  308. } else if (prop.contains("对方主体名称")) {
  309. detail.put("bizAlias","contract_opposite_company_name");
  310. }
  311. details.add(detail);
  312. }
  313. lastList.add(details);
  314. }
  315. formData.put( "value", JSON.toJSONString(lastList));
  316. formData.put( "name",((Map) meta.get(code)).get(split[1]).toString());
  317. }else {
  318. List<Map> details = new ArrayList<>();
  319. for (String prop : compIds.keySet()) {
  320. Map detail = UtilMap.empty();
  321. if ("quantity".equals(compIds.get(prop))){
  322. detail.put("value", "0");
  323. detail.put("name", prop);
  324. }else {
  325. detail.put("value", "无");
  326. detail.put("name", prop);
  327. }
  328. details.add(detail);
  329. }
  330. lastList.add(details);
  331. formData.put( "value", JSON.toJSONString(lastList));
  332. formData.put( "name",((Map) meta.get(code)).get(split[1]).toString());
  333. }
  334. } else {
  335. if (data.containsKey(component.get(key))){
  336. if (ObjectUtil.isNotNull(data.get(component.get(key)))){
  337. Object value = data.get(component.get(key));
  338. formData.put("name", key);
  339. formData.put("value",value.toString());
  340. if ("RelatedReceipt".equals(component.get(key))){
  341. List<String> ids = new ArrayList<>();
  342. ids.add(value.toString());
  343. formData.put("name", key);
  344. formData.put("value",JSON.toJSONString(ids));
  345. }
  346. if (ALLENUM.containsKey(value.toString())){
  347. formData.put("value",ALLENUM.get(value.toString()));
  348. }
  349. }
  350. }
  351. }
  352. if (formData.size()>0){
  353. formValue.add(formData);
  354. }
  355. }
  356. final String[] token = {""};
  357. final boolean[] isHave = {false};
  358. ATTACHMENT_ENUM.forEach((k,v)->{
  359. if (data.containsKey(k) && hasValid(data,k)){
  360. log.info("开始处理附件上传");
  361. List<Map> attachment = (List<Map>) data.get(k);
  362. List<Map<String, Object>> resultList = new ArrayList<>();
  363. attachment.forEach(e->{
  364. String[] split = UtilMap.getString(e, "name").split("\\.");
  365. String fileName = split[0];
  366. if (split.length > 2){
  367. for (int i = 1; i < split.length -1; i++) {
  368. fileName = fileName + "." + split[i];
  369. }
  370. }
  371. String fileType = split[split.length-1];
  372. Map map = ddService.uploadFileFormUrlForOverflow(ddClient.getAccessToken(), "02145933103936490950", e.get("downloadUrl").toString() + "?token=" + token[0], fileName, fileType);
  373. // Map map = ddService.uploadFileFormUrlForOverflow(ddClient.getAccessToken(), data.get(((Map) meta.get(code)).get("creator")).toString(), e.get("downloadUrl").toString() + "?token=" + token[0], fileName, fileType);
  374. Map<String, Object> result = UtilMap.map("spaceId, fileName, fileSize, fileType, fileId", UtilMap.getString(map, "spaceId"), fileName,
  375. UtilMap.getString(map, "size"), UtilMap.getString(map, "extension"), UtilMap.getString(map, "id"));
  376. resultList.add(result);
  377. });
  378. formValue.add(UtilMap.map("name, value",v,JSON.toJSONString(resultList)));
  379. }
  380. });
  381. }
  382. /**
  383. * 整合传参及OA数据格式
  384. * @param code 单据类型
  385. * @param data 传参
  386. * @return 流程实例id
  387. */
  388. private String dataProcessing(String code, Map data){
  389. //加载json映射
  390. Map meta = _getMeta();
  391. //表单字段映射
  392. List<Map> formValue = new ArrayList<>();
  393. log.info("code:{} ",code);
  394. IntegrationData(code, data, meta, formValue);
  395. List<String> workingEmployeeIds = new ArrayList<>();
  396. workingEmployeeIds.add(data.get(((Map) meta.get(code)).get("creator")).toString());
  397. List<String> deptIdByUserId = getDeptIdByUserId(workingEmployeeIds);
  398. if (code.startsWith("HTSPD")){
  399. formValue.add(UtilMap.map("name, value","发起部门",deptIdByUserId.get(0)));
  400. formValue.add(UtilMap.map("name, value","合同编号生成方式, 选择已有合同编号"));
  401. // formValue.add(UtilMap.map("name, value","合同编号规则, 测试合同编号"));
  402. return ddClient_workflow.doProcessInstancesNew(ddClient.getAccessToken(), data.get(((Map) meta.get(code)).get("creator")).toString(),((Map) meta.get(code)).get("processCode").toString(), formValue, deptIdByUserId.get(0));
  403. // return ddClient_workflow.doProcessInstancesNew(ddClient.getAccessToken(), data.get(((Map) meta.get(code)).get("creator")).toString(), "PROC-B5E48D42-87FA-4C4E-9CD8-9178EEF1F0D3", formValue, deptIdByUserId.get(0));
  404. }
  405. return ddClient_workflow.doProcessInstancesNew(ddClient.getAccessToken(), data.get(((Map) meta.get(code)).get("creator")).toString(), ((Map) meta.get(code)).get("processCode").toString(), formValue, deptIdByUserId.get(0));
  406. // return code;
  407. }
  408. /**
  409. * 发起流程审批
  410. * @param code
  411. * @param data
  412. * @return 流程实例id和地址
  413. */
  414. @Override
  415. public Map<String, Object> startProcess(String code, Map data) {
  416. String instanceId = dataProcessing(code, data);
  417. JSONObject jsonObject = JSONObject.parseObject(instanceId);
  418. if (!ObjectUtil.isNotNull(jsonObject.get("instanceId"))){
  419. return UtilMap.map("ddProcessId, dtUrl, reqMsg", jsonObject.get("instanceId"), "error", instanceId);
  420. }
  421. String url = "https://applink.dingtalk.com/approval/detail?corpId=ding226da4276814d290a1320dcb25e91351&instanceId=" + jsonObject.get("instanceId");
  422. return UtilMap.map("ddProcessId, dtUrl, reqMsg", jsonObject.get("instanceId"), url, instanceId);
  423. }
  424. /**
  425. * object附件判空
  426. * @param data
  427. * @param key
  428. * @return
  429. */
  430. public boolean hasValid(Map data,String key) {
  431. Object flowObj = data.get(key);
  432. if (ObjectUtil.isNull(flowObj)) {
  433. return false;
  434. }
  435. if (!(flowObj instanceof List)) {
  436. return false;
  437. }
  438. List<?> flowList = (List<?>) flowObj;
  439. if (flowList.isEmpty()) {
  440. return false;
  441. }
  442. for (Object item : flowList) {
  443. if (item instanceof Map) {
  444. Map<?, ?> itemMap = (Map<?, ?>) item;
  445. Object url = itemMap.get("downloadUrl");
  446. if (url != null && !url.toString().trim().isEmpty()) {
  447. return true;
  448. }
  449. }
  450. }
  451. return false;
  452. }
  453. @Override
  454. public String startProcess(Map data) {
  455. DDR_New ddr_new = ydClient.queryData(YDParam.builder()
  456. .appType(appType)
  457. .systemToken(systemToken)
  458. .formInstanceId(UtilMap.getString(data, "formInstanceId"))
  459. .build(),
  460. YDConf.FORM_QUERY.retrieve_id_new);
  461. Map formData = ddr_new.getFormData();
  462. Map originator = ddr_new.getOriginator();
  463. String userId = UtilMap.getString(originator, "userId");
  464. //所有附件类型使用
  465. List<Map<String, Object>> resultList = new ArrayList<>();
  466. //写入OA审批的数据格式
  467. List<Map> formValue = new ArrayList<>();
  468. //附件
  469. String key = UtilMap.getString(data, "attachmentKey");
  470. String value = UtilMap.getString(formData, key);
  471. resultList.add(UtilMap.map("spaceId, fileName, fileSize, fileType, fileId", UtilMap.getString(formData, "textField_msve6for"),
  472. UtilMap.getString(formData, "textField_msve6fos"), UtilMap.getString(formData, "textField_msve6fot"),
  473. UtilMap.getString(formData, "textField_msve6fou"), UtilMap.getString(formData, "textField_msve6fox")));
  474. //处理宜搭附件绑定至OA审批
  475. JSONArray jsonArray = JSONArray.parseArray(value);
  476. if (ObjectUtil.isNotNull(jsonArray) && jsonArray.size()>0){
  477. jsonArray.forEach(e->{
  478. JSONObject jsonObject = JSONObject.parseObject(e.toString());
  479. String downloadUrl = jsonObject.getString("downloadUrl");
  480. String fileFullName = jsonObject.getString("name");
  481. String url = ydClient.convertTemporaryUrl(downloadUrl, appType, systemToken);
  482. Map map = ddService.uploadFileFormUrlForOverflow(ddClient.getAccessToken(), userId, url, fileFullName, fileFullName.split("\\.")[1]);
  483. Map<String, Object> result = UtilMap.map("spaceId, fileName, fileSize, fileType, fileId", UtilMap.getString(map, "spaceId"), fileFullName,
  484. UtilMap.getString(map, "size"), UtilMap.getString(map, "extension"), UtilMap.getString(map, "id"));
  485. resultList.add(result);
  486. });
  487. }
  488. formValue.add(UtilMap.map("name, value","合同正文, " + JSON.toJSONString(resultList)));
  489. //合同编号生成方式
  490. formValue.add(UtilMap.map("name, value","合同编号生成方式, 手动填写"));
  491. key = UtilMap.getString(data, "sealType");
  492. value = UtilMap.getString(formData, key);
  493. //印章类型
  494. formValue.add(UtilMap.map("name, value","印章类型, " + value));
  495. // formValue.add(UtilMap.map("name, value","印章类型, " + "公章"));
  496. //合同编号
  497. key = UtilMap.getString(data, "codeKey");
  498. value = UtilMap.getString(formData, key);
  499. formValue.add(UtilMap.map("name, value","合同编号, " + value));
  500. //合同名称
  501. key = UtilMap.getString(data, "nameKey");
  502. value = UtilMap.getString(formData, key);
  503. formValue.add(UtilMap.map("name, value","合同名称, " + value));
  504. //金额类型
  505. key = UtilMap.getString(data, "amountType");
  506. if ("/".equals(key)){
  507. formValue.add(UtilMap.map("name, value","金额类型, 无金额"));
  508. }else {
  509. value = UtilMap.getString(formData, key);
  510. formValue.add(UtilMap.map("name, value","金额类型, " + AMOUNT_TYPE.get(value)));
  511. }
  512. //合同总额(元)
  513. key = UtilMap.getString(data, "totalAmount");
  514. if ("/".equals(key)){
  515. formValue.add(UtilMap.map("name, value","合同总额(元), 0"));
  516. }else {
  517. value = UtilMap.getString(formData, key);
  518. formValue.add(UtilMap.map("name, value","合同总额(元), " + value));
  519. }
  520. //合同期限开始日期
  521. key = UtilMap.getString(data, "startTime");
  522. //固定合同期限类型
  523. if ("/".equals(key)){
  524. formValue.add(UtilMap.map("name, value","合同期限类型, 非固定期限"));
  525. }else {
  526. formValue.add(UtilMap.map("name, value","合同期限类型, 固定期限"));
  527. value = UtilMap.getString(formData, key);
  528. // List list = UtilMap.getList(formData, key);
  529. String startFormat = LocalDateTime.ofInstant(
  530. // Instant.ofEpochMilli(Long.parseLong(list.get(0).toString())),
  531. Instant.ofEpochMilli(Long.parseLong(value)),
  532. ZoneId.of("Asia/Shanghai")
  533. ).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
  534. formValue.add(UtilMap.map("name, value","合同期限开始日期, " + startFormat));
  535. //合同期限结束日期
  536. key = UtilMap.getString(data, "endTime");
  537. value = UtilMap.getString(formData, key);
  538. String endFormat = LocalDateTime.ofInstant(
  539. Instant.ofEpochMilli(Long.parseLong(value)),
  540. ZoneId.of("Asia/Shanghai")
  541. ).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
  542. formValue.add(UtilMap.map("name, value","合同期限结束日期, " + endFormat));
  543. }
  544. //用印形式
  545. key = UtilMap.getString(data, "useSeal");
  546. value = UtilMap.getString(formData, key);
  547. //签署方式
  548. if("双方物理用印".equals(value)){
  549. formValue.add(UtilMap.map("name, value","签署方式, 纸质签署"));
  550. }else {
  551. formValue.add(UtilMap.map("name, value","签署方式, 电子签署"));
  552. }
  553. if (data.containsKey("otherAttachment")){
  554. //合同附件
  555. key = UtilMap.getString(data, "otherAttachment");
  556. value = UtilMap.getString(formData, key);
  557. //处理宜搭附件绑定至OA审批
  558. jsonArray = JSONArray.parseArray(value);
  559. if(ObjectUtil.isNotNull(jsonArray)&& jsonArray.size()>0){
  560. resultList.clear();
  561. jsonArray.forEach(e->{
  562. JSONObject jsonObject = JSONObject.parseObject(e.toString());
  563. String downloadUrl = jsonObject.getString("downloadUrl");
  564. String fileFullName = jsonObject.getString("name");
  565. String url = ydClient.convertTemporaryUrl(downloadUrl, appType, systemToken);
  566. Map map = ddService.uploadFileFormUrlForOverflow(ddClient.getAccessToken(), userId, url, fileFullName, fileFullName.split("\\.")[1]);
  567. Map<String, Object> result = UtilMap.map("spaceId, fileName, fileSize, fileType, fileId", UtilMap.getString(map, "spaceId"), fileFullName,
  568. UtilMap.getString(map, "size"), UtilMap.getString(map, "extension"), UtilMap.getString(map, "id"));
  569. resultList.add(result);
  570. });
  571. formValue.add(UtilMap.map("name, value","合同附件, " + JSON.toJSONString(resultList)));
  572. }
  573. }
  574. //我方主体
  575. List<List<Map>> ourLastList = new ArrayList<>();
  576. List<Map> ourDetails = new ArrayList<>();
  577. key = UtilMap.getString(data, "ourDetail");
  578. if ("/".equals(key)){
  579. Map ourDetail = UtilMap.empty();
  580. ourDetail.put("value", "/");
  581. ourDetail.put("name", "我方主体名称");
  582. ourDetail.put("bizAlias","contract_mine_company_name");
  583. ourDetails.add(ourDetail);
  584. }else {
  585. String[] split = key.split(",");
  586. for (int i = 0; i < split.length; i++) {
  587. value = UtilMap.getString(formData, split[i]);
  588. Map ourDetail = UtilMap.empty();
  589. ourDetail.put("value", value);
  590. ourDetail.put("name", "我方主体名称");
  591. ourDetail.put("bizAlias","contract_mine_company_name");
  592. ourDetails.add(ourDetail);
  593. }
  594. }
  595. // ourDetails.add(UtilMap.map("name, value", "我方负责人, 待补充"));
  596. ourLastList.add(ourDetails);
  597. formValue.add(UtilMap.map("name, value","我方信息",JSON.toJSONString(ourLastList)));
  598. //他方主体
  599. List<List<Map>> otherLastList = new ArrayList<>();
  600. List<Map> otherDetails = new ArrayList<>();
  601. key = UtilMap.getString(data, "otherDetail");
  602. if ("/".equals(key)){
  603. Map otherDetail = UtilMap.empty();
  604. otherDetail.put("value", "/");
  605. otherDetail.put("name", "对方主体名称");
  606. otherDetail.put("bizAlias", "contract_opposite_company_name");
  607. otherDetails.add(otherDetail);
  608. }else {
  609. String[] split = key.split(",");
  610. for (int i = 0; i < split.length; i++) {
  611. value = UtilMap.getString(formData, split[i]);
  612. Map otherDetail = UtilMap.empty();
  613. otherDetail.put("value", value);
  614. otherDetail.put("name", "对方主体名称");
  615. otherDetail.put("bizAlias", "contract_opposite_company_name");
  616. otherDetails.add(otherDetail);
  617. }
  618. }
  619. // otherDetails.add(UtilMap.map("name, value", "对方负责人, 待补充"));
  620. otherLastList.add(otherDetails);
  621. formValue.add(UtilMap.map("name, value","对方信息",JSON.toJSONString(otherLastList)));
  622. List<String> workingEmployeeIds = new ArrayList<>();
  623. workingEmployeeIds.add(userId);
  624. List<String> deptIdByUserId = getDeptIdByUserId(workingEmployeeIds);
  625. return ddClient_workflow.doProcessInstancesNew(ddClient.getAccessToken(), userId,"PROC-CCD914BE-E89B-4E4B-B5D3-9569BF26AE22", formValue, deptIdByUserId.get(0));
  626. }
  627. @Override
  628. public McR createSubjectInfo(Map data) {
  629. List<Map> dataList = ydService.queryFormData_all(YDParam.builder()
  630. .appType(appType)
  631. .systemToken(systemToken)
  632. .formUuid("FORM-DA83FE32D61F49299DA6F8E8F992BCE9CKWE")
  633. // .searchFieldJson(JSON.toJSONString(UtilMap.map("textField_mrlipwdt", "332624199910200042424")))
  634. .searchFieldJson(JSON.toJSONString(UtilMap.map("textField_mrlipwdt", UtilMap.getString(data,"creditCode"))))
  635. .build());
  636. String staffId = UtilMap.getString(data, "staffId");
  637. JSONArray array= JSONArray.parseArray(staffId);
  638. staffId = array.get(0).toString();
  639. if (dataList.isEmpty()){
  640. String url = "https://connector.dingtalk.com/webhook/subflow/6f842eadb97994cceaa04991";
  641. data.put("staffId",staffId);
  642. String jsonBody = JSON.toJSONString(data);
  643. log.info("发起HTTP请求 URL={}, 请求体={}", url, jsonBody);
  644. try {
  645. HttpResponse response = HttpRequest.post(url)
  646. .header("Content-Type", "application/json")
  647. .body(jsonBody)
  648. .execute();
  649. String responseBody = response.body();
  650. int status = response.getStatus();
  651. log.info("HTTP响应 URL={}, status={}, 响应体={}", url, status, responseBody);
  652. if (status == 200) {
  653. // 解析远端返回的统一响应结构
  654. return McR.success(responseBody);
  655. } else {
  656. log.error("HTTP请求失败 URL={}, status={}, body={}", url, status, responseBody);
  657. return McR.error(String.valueOf(status),responseBody);
  658. }
  659. } catch (Exception e) {
  660. log.error("HTTP请求异常 URL={}", url, e);
  661. McR.errorParam("HTTP请求异常: " + e.getMessage());
  662. }
  663. }else {
  664. String finalStaffId = staffId;
  665. dataList.forEach(e->{
  666. String emp = UtilMap.getString(e, "employeeField_msczhgcx_id");
  667. JSONArray jsonArray = JSONArray.parseArray(emp);
  668. jsonArray.add(finalStaffId);
  669. // creatorUserId
  670. ydClient.operateData(YDParam.builder()
  671. .appType(appType)
  672. .systemToken(systemToken)
  673. .formInstanceId(UtilMap.getString(e, "formInstanceId"))
  674. .useLatestVersion(true)
  675. .updateFormDataJson(JSON.toJSONString(UtilMap.map("employeeField_msczhgcx", jsonArray)))
  676. .build(), YDConf.FORM_OPERATION.update);
  677. });
  678. try {
  679. Thread.sleep(16000);
  680. } catch (InterruptedException e) {
  681. throw new RuntimeException(e);
  682. }
  683. ydClient.operateData(YDParam.builder()
  684. .appType(appType)
  685. .systemToken(systemToken)
  686. .processInstanceId(UtilMap.getString(data, "formInstanceId"))
  687. .build(), YDConf.FORM_OPERATION.terminate);
  688. }
  689. return McR.success("该相对方已存在");
  690. }
  691. }