Create_by_fileOSFService.java 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901
  1. package com.kingdee.eas.custom.esign.osf;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONArray;
  4. import com.alibaba.fastjson.JSONObject;
  5. import com.google.common.collect.Lists;
  6. import com.google.common.collect.Maps;
  7. import com.google.common.collect.Sets;
  8. import com.kingdee.bos.BOSException;
  9. import com.kingdee.bos.Context;
  10. import com.kingdee.bos.bsf.service.app.IHRMsfService;
  11. import com.kingdee.eas.common.EASBizException;
  12. import com.kingdee.eas.custom.esign.bizEnum.ComponentTypeEnum;
  13. import com.kingdee.eas.custom.esign.bizEnum.EsignStatusEnum;
  14. import com.kingdee.eas.custom.esign.tsign.hz.comm.EsignHttpResponse;
  15. import com.kingdee.eas.custom.esign.tsign.hz.exception.EsignException;
  16. import com.kingdee.eas.custom.esign.util.EsignConfig;
  17. import com.kingdee.eas.custom.esign.util.EsignHttpUtil;
  18. import org.apache.commons.lang3.StringUtils;
  19. import java.net.URISyntaxException;
  20. import java.util.*;
  21. import java.util.concurrent.TimeUnit;
  22. /**
  23. * description: Create_by_fileOSFService <br>
  24. * date: 28/11/2025 上午 9:46 <br>
  25. * author: lhbj <br>
  26. * version: 1.0 <br>
  27. */
  28. public class Create_by_fileOSFService implements IHRMsfService {
  29. private static final String SUCCESS_CODE = "0";
  30. private static final String PREVIEW_OPERATION = "预览";
  31. private static final int MAX_RETRY_COUNT = 20;
  32. private static final int RETRY_INTERVAL_SECONDS = 3;
  33. @Override
  34. public Object process(Context context, Map map) throws EASBizException, BOSException {
  35. String mack = (String) map.get("mack");
  36. String data = (String) map.get("data");
  37. Map<String, Object> resul = Maps.newHashMap();
  38. try {
  39. JSONObject jsonObject = JSON.parseObject(data);
  40. if ("preview".equals(mack)) {
  41. for (Map.Entry<String, Object> fileEntry : jsonObject.entrySet()) {
  42. JSONObject fieldObject = (JSONObject) fileEntry.getValue();
  43. EsignHttpResponse response = this.previewFile(context, fieldObject, "预览");
  44. if (response.getStatus() >= 200 && response.getStatus() < 300) {
  45. resul.putAll(this.processFileResponse(response, context));
  46. } else {
  47. resul.put("code", response.getStatus());
  48. resul.put("message", "网络异常");
  49. resul.put("data", null);
  50. }
  51. }
  52. } else {
  53. Map<String, Object> signMap = Maps.newHashMap();
  54. String sourceId = jsonObject.getString("sourceId");
  55. String signFlowTitle = jsonObject.getString("signFlowTitle");
  56. String personId = jsonObject.getString("personId");
  57. String operatorId = jsonObject.getString("operatorId");
  58. //文件
  59. JSONObject templateInfo = jsonObject.getJSONObject("templateInfo");
  60. //设置待签署文件信息
  61. List<Map<String, Object>> docs = null;
  62. try {
  63. docs = this.addDocs(context, jsonObject, templateInfo);
  64. List<Map<String, Object>> signDocs = Lists.newArrayList();
  65. for (Map<String, Object> doc : docs) {
  66. Map<String, Object> docNew = new HashMap<>(doc);
  67. docNew.remove("signListGroup");
  68. signDocs.add(docNew);
  69. }
  70. signMap.put("docs", signDocs);
  71. } catch (EsignException e) {
  72. e.printStackTrace();
  73. resul.putAll(JSON.parseObject(e.getMessage()));
  74. }
  75. if (null != docs) {
  76. //签署流程配置项
  77. Map<String, Object> signFlowConfig = this.addSignFlowConfig(context, signFlowTitle, jsonObject);
  78. signMap.put("signFlowConfig", signFlowConfig);
  79. //签署方信息
  80. JSONObject signInfo = jsonObject.getJSONObject("signInfo");
  81. JSONArray signs = signInfo.getJSONArray("signers");
  82. List<Map<String, Object>> signers = this.addSigners(context, signs, docs, sourceId);
  83. signMap.put("signers", signers);
  84. //抄送方信息
  85. JSONArray copis = signInfo.getJSONArray("copiers");
  86. List<Map<String, Object>> copiers = this.addCopiers(context, copis);
  87. if (copiers.size() > 0) {
  88. signMap.put("copiers", copiers);
  89. }
  90. //必须要存在签署文件才能签署
  91. if (docs.size() > 0) {
  92. System.out.println("--------------------------------------------------------------------------------------");
  93. System.out.println("signMap:" + JSON.toJSONString(signMap));
  94. System.out.println("--------------------------------------------------------------------------------------");
  95. EsignHttpResponse response = EsignHttpUtil.create_by_file(context, personId, signFlowTitle, operatorId, sourceId, JSON.toJSONString(signMap));
  96. if (response.getStatus() >= 200 && response.getStatus() < 300) {
  97. JSONObject body = JSON.parseObject(response.getBody());
  98. resul.putAll(body);
  99. } else {
  100. resul.put("code", response.getStatus());
  101. resul.put("message", "网络异常");
  102. resul.put("data", null);
  103. }
  104. }
  105. }
  106. }
  107. } catch (EsignException | URISyntaxException e) {
  108. e.printStackTrace();
  109. resul.put("code", 400);
  110. resul.put("message", e.getMessage());
  111. resul.put("data", null);
  112. }
  113. return resul;
  114. }
  115. /**
  116. * 根据”填写模板生成文件“返回的文件id查询文件处理状态
  117. * 需要阻塞等待这个状态变为2或者5才能调用发起签署接口
  118. *
  119. * @param response
  120. * @param context
  121. * @return
  122. */
  123. public Map<String, Object> processFileResponse(EsignHttpResponse response, Context context) {
  124. Map<String, Object> result = Maps.newHashMap();
  125. JSONObject body = JSON.parseObject(response.getBody());
  126. if (!SUCCESS_CODE.equals(String.valueOf(body.get("code")))) {
  127. result.putAll(body);
  128. return result;
  129. }
  130. JSONObject jsonData = body.getJSONObject("data");
  131. String fileId = jsonData.getString("fileId");
  132. JSONObject pollData = pollFileDownloadUrl(context, fileId);
  133. if (null != pollData && StringUtils.isNotBlank(pollData.getString("fileDownloadUrl"))) {
  134. jsonData.putAll(pollData);
  135. }
  136. result.putAll(body);
  137. System.out.println("processFileResponse:" + result);
  138. return result;
  139. }
  140. /**
  141. * 阻塞循环调用获取文件信息接口
  142. *
  143. * @param context
  144. * @param fileId
  145. * @return
  146. */
  147. private JSONObject pollFileDownloadUrl(Context context, String fileId) {
  148. for (int i = MAX_RETRY_COUNT; i > 0; i--) {
  149. try {
  150. JSONObject data = tryGetFileDownloadUrl(context, fileId);
  151. if (null != data && StringUtils.isNotBlank(data.getString("fileDownloadUrl"))) {
  152. return data;
  153. }
  154. TimeUnit.SECONDS.sleep(RETRY_INTERVAL_SECONDS);
  155. } catch (InterruptedException e) {
  156. Thread.currentThread().interrupt();
  157. break;
  158. } catch (Exception e) {
  159. // 记录日志,继续重试
  160. e.printStackTrace();
  161. }
  162. }
  163. return null;
  164. }
  165. /**
  166. * 等待这个状态变为2或者5才返回
  167. *
  168. * @param context
  169. * @param fileId
  170. * @return
  171. */
  172. private JSONObject tryGetFileDownloadUrl(Context context, String fileId) {
  173. try {
  174. EsignHttpResponse response = EsignHttpUtil.getFileStatus(context, fileId, PREVIEW_OPERATION);
  175. if (response.getStatus() < 200 || response.getStatus() >= 300) {
  176. return null;
  177. }
  178. JSONObject responseBody = JSON.parseObject(response.getBody());
  179. if (!SUCCESS_CODE.equals(String.valueOf(responseBody.get("code")))) {
  180. return null;
  181. }
  182. JSONObject data = responseBody.getJSONObject("data");
  183. String fileStatus = data.getString("fileStatus");
  184. Set<String> COMPLETED_STATUS = Sets.newHashSet();
  185. COMPLETED_STATUS.add("2");
  186. COMPLETED_STATUS.add("5");
  187. if (COMPLETED_STATUS.contains(fileStatus)) {
  188. return data;
  189. }
  190. } catch (EsignException e) {
  191. e.printStackTrace();
  192. }
  193. return null;
  194. }
  195. /**
  196. * 设置待签署文件位置信息
  197. *
  198. * @param context
  199. * @param fileId
  200. * @param keyword
  201. * @param sourceId
  202. * @return
  203. * @throws EsignException
  204. */
  205. public JSONObject addPositions(Context context, String fileId, String keyword, String sourceId) throws EsignException {
  206. List<String> keywords = Lists.newArrayList();
  207. keywords.add(keyword);
  208. JSONObject coordinate = null;
  209. System.out.println("respPosition:fileId:" + fileId);
  210. System.out.println("respPosition:keywords:" + keywords);
  211. EsignHttpResponse respPosition = EsignHttpUtil.keyword_positions(context, fileId, keywords, sourceId);
  212. System.out.println("respPosition:" + respPosition.getBody());
  213. if (respPosition.getStatus() >= 200 && respPosition.getStatus() < 300) {
  214. JSONObject resp = JSON.parseObject(respPosition.getBody());
  215. if ("0".equals(String.valueOf(resp.get("code")))) {
  216. JSONObject keywordData = (JSONObject) resp.get("data");
  217. if (null != keywordData) {
  218. JSONArray keywordPositions = keywordData.getJSONArray("keywordPositions");
  219. if (null != keywordPositions && keywordPositions.size() > 0) {
  220. JSONObject keywordPs = keywordPositions.getJSONObject(keywordPositions.size() - 1);
  221. if (keywordPs.getBoolean("searchResult")) {
  222. if (null != keywordPs) {
  223. JSONArray positions = keywordPs.getJSONArray("positions");
  224. if (null != positions && positions.size() > 0) {
  225. JSONObject position = positions.getJSONObject(positions.size() - 1);
  226. if (null != position) {
  227. Object pageNum = position.get("pageNum");
  228. JSONArray coordinates = position.getJSONArray("coordinates");
  229. if (null != coordinates && coordinates.size() > 0) {
  230. coordinate = coordinates.getJSONObject(coordinates.size() - 1);
  231. if (null != coordinate) {
  232. coordinate.put("positionPage", pageNum);
  233. }
  234. }
  235. }
  236. }
  237. }
  238. }
  239. }
  240. }
  241. }
  242. System.out.println("coordinate:" + coordinate);
  243. }
  244. return coordinate;
  245. }
  246. /**
  247. * 获取签署人的签署区
  248. *
  249. * @param context
  250. * @param fields
  251. * @param fileId
  252. * @param sourceId
  253. * @return
  254. * @throws EsignException
  255. */
  256. public Map<String, List<Map<String, Object>>> addsignAreaList(Context context, Map<String, Object> fields, String fileId, String sourceId) throws EsignException {
  257. Map<String, List<Map<String, Object>>> signListGroup = Maps.newHashMap();
  258. for (Map.Entry<String, Object> field : fields.entrySet()) {
  259. String componentId = field.getKey();
  260. JSONObject fieldInfo = (JSONObject) field.getValue();
  261. Object componentValue = fieldInfo.get("value");
  262. Double positionX = fieldInfo.getDouble("positionX");
  263. Double positionY = fieldInfo.getDouble("positionY");
  264. Object pageNum = fieldInfo.get("pageNum");
  265. String name = fieldInfo.getString("name");
  266. String dataType = fieldInfo.getString("dataType");
  267. if (ComponentTypeEnum.SIGN_AREA.getAlias().equals(dataType)) {
  268. Map<String, Object> signMap = Maps.newHashMap();
  269. String[] keys = name.split("_");
  270. String key = "签署方";
  271. for (String k : keys) {
  272. if (k.startsWith("签署方")) {
  273. key = k;
  274. break;
  275. }
  276. }
  277. signMap.put("key", key);
  278. signMap.put("fileId", fileId);
  279. signMap.put("signFieldType", 0);
  280. String keyword = keys[0];
  281. if (keyword.indexOf("骑缝") >= 0) {
  282. signMap.put("signFieldStyle", 2);
  283. } else {
  284. if (null == positionX || null == positionY) {
  285. signMap.put("signFieldStyle", 1);
  286. JSONObject coordinate = this.addPositions(context, fileId, keyword, sourceId);
  287. System.out.println("doc.coordinate:" + coordinate);
  288. if (null != coordinate) {
  289. double posX = coordinate.getDouble("positionX");
  290. double posY = coordinate.getDouble("positionY");
  291. for (String k : keys) {
  292. if (k.startsWith("X")) {
  293. String x = k.replace("X", "");
  294. posX = posX + Integer.parseInt(x);
  295. signMap.put("posX", posX);
  296. break;
  297. }
  298. }
  299. for (String k : keys) {
  300. if (k.startsWith("Y")) {
  301. String y = k.replace("Y", "");
  302. posY = posY + Integer.parseInt(y);
  303. signMap.put("posY", posY);
  304. break;
  305. }
  306. }
  307. signMap.put("positionX", coordinate.getDouble("positionX"));
  308. signMap.put("positionY", coordinate.getDouble("positionY"));
  309. signMap.put("positionPage", coordinate.get("positionPage"));
  310. }
  311. } else {
  312. double posX = positionX;
  313. double posY = positionY;
  314. for (String k : keys) {
  315. if (k.startsWith("X")) {
  316. String x = k.replace("X", "");
  317. posX = posX + Integer.parseInt(x);
  318. signMap.put("posX", posX);
  319. break;
  320. }
  321. }
  322. for (String k : keys) {
  323. if (k.startsWith("Y")) {
  324. String y = k.replace("Y", "");
  325. posY = posY + Integer.parseInt(y);
  326. signMap.put("posY", posY);
  327. break;
  328. }
  329. }
  330. signMap.put("positionX", positionX);
  331. signMap.put("positionY", positionY);
  332. signMap.put("positionPage", pageNum);
  333. }
  334. }
  335. List<Map<String, Object>> signList = signListGroup.get((String) signMap.get("key"));
  336. if (null == signList) {
  337. signList = Lists.newArrayList();
  338. signListGroup.put((String) signMap.get("key"), signList);
  339. }
  340. signList.add(signMap);
  341. } else if (ComponentTypeEnum.REMARK_SIGN_AREA.getAlias().equals(dataType)) {
  342. Map<String, Object> signMap = Maps.newHashMap();
  343. String[] keys = name.split("_");
  344. String key = "签署方";
  345. for (String k : keys) {
  346. if (k.startsWith("签署方")) {
  347. key = k;
  348. break;
  349. }
  350. }
  351. signMap.put("key", key);
  352. signMap.put("fileId", fileId);
  353. signMap.put("signFieldType", 1);
  354. String keyword = keys[0];
  355. if (keyword.indexOf("骑缝") >= 0) {
  356. signMap.put("signFieldStyle", 2);
  357. } else {
  358. if (null == positionX || null == positionY) {
  359. signMap.put("signFieldStyle", 1);
  360. JSONObject coordinate = this.addPositions(context, fileId, keyword, sourceId);
  361. System.out.println("doc.coordinate:" + coordinate);
  362. if (null != coordinate) {
  363. double posX = coordinate.getDouble("positionX");
  364. double posY = coordinate.getDouble("positionY");
  365. for (String k : keys) {
  366. if (k.startsWith("X")) {
  367. String x = k.replace("X", "");
  368. posX = posX + Integer.parseInt(x);
  369. signMap.put("posX", posX);
  370. break;
  371. }
  372. }
  373. for (String k : keys) {
  374. if (k.startsWith("Y")) {
  375. String y = k.replace("Y", "");
  376. posY = posY + Integer.parseInt(y);
  377. signMap.put("posY", posY);
  378. break;
  379. }
  380. }
  381. signMap.put("positionX", coordinate.getDouble("positionX"));
  382. signMap.put("positionY", coordinate.getDouble("positionY"));
  383. signMap.put("positionPage", coordinate.get("positionPage"));
  384. }
  385. } else {
  386. double posX = positionX;
  387. double posY = positionY;
  388. for (String k : keys) {
  389. if (k.startsWith("X")) {
  390. String x = k.replace("X", "");
  391. posX = posX + Integer.parseInt(x);
  392. signMap.put("posX", posX);
  393. break;
  394. }
  395. }
  396. for (String k : keys) {
  397. if (k.startsWith("Y")) {
  398. String y = k.replace("Y", "");
  399. posY = posY + Integer.parseInt(y);
  400. signMap.put("posY", posY);
  401. break;
  402. }
  403. }
  404. signMap.put("positionX", positionX);
  405. signMap.put("positionY", positionY);
  406. signMap.put("positionPage", pageNum);
  407. }
  408. }
  409. List<Map<String, Object>> signList = signListGroup.get((String) signMap.get("key"));
  410. if (null == signList) {
  411. signList = Lists.newArrayList();
  412. signListGroup.put((String) signMap.get("key"), signList);
  413. }
  414. signList.add(signMap);
  415. }
  416. }
  417. System.out.println("signListGroup:" + signListGroup);
  418. return signListGroup;
  419. }
  420. /**
  421. * 设置待签署文件信息
  422. *
  423. * @param context
  424. * @param jsonObject
  425. * @param templateInfo
  426. * @return
  427. * @throws EsignException
  428. */
  429. public List<Map<String, Object>> addDocs(Context context, JSONObject jsonObject, JSONObject templateInfo) throws EsignException {
  430. //设置待签署文件信息
  431. Map<String, Object> resul = Maps.newHashMap();
  432. List<Map<String, Object>> docs = Lists.newArrayList();
  433. for (Map.Entry<String, Object> fileEntry : templateInfo.entrySet()) {
  434. JSONObject fieldObject = (JSONObject) fileEntry.getValue();
  435. String docTemplateId = fieldObject.getString("id");
  436. String fileName = fieldObject.getString("name");
  437. Object order = fieldObject.get("order");
  438. String sourceId = jsonObject.getString("sourceId");
  439. EsignHttpResponse response = this.previewFile(context, fieldObject, sourceId);
  440. resul.put("id", docTemplateId);
  441. resul.put("name", fileName);
  442. if (response.getStatus() >= 200 && response.getStatus() < 300) {
  443. Map<String, Object> body = this.processFileResponse(response, context);
  444. if ("0".equals(String.valueOf(body.get("code")))) {
  445. JSONObject file = (JSONObject) body.get("data");
  446. Map<String, Object> doc = Maps.newHashMap();
  447. doc.put("fileId", file.get("fileId"));
  448. doc.put("fileName", fileName);
  449. if (null != order) {
  450. doc.put("order", Integer.parseInt(String.valueOf(order)));
  451. }
  452. doc.put("positionX", null);
  453. doc.put("positionY", null);
  454. doc.put("positionPage", null);
  455. System.out.println("addDocs:" + fieldObject);
  456. JSONObject fields = fieldObject.getJSONObject("fields");
  457. //取得这个文件的签署人的签署区
  458. Map<String, List<Map<String, Object>>> signAreaList = this.addsignAreaList(context, fields, (String) file.get("fileId"), sourceId);
  459. doc.put("signListGroup", signAreaList);
  460. docs.add(doc);
  461. } else {
  462. //文件模板生成失败
  463. resul.putAll(body);
  464. throw new EsignException(JSON.toJSONString(resul));
  465. }
  466. } else {
  467. throw new EsignException(JSON.toJSONString(response));
  468. }
  469. }
  470. return docs;
  471. }
  472. /**
  473. * 抄送方信息
  474. *
  475. * @param copis
  476. * @return
  477. */
  478. public List<Map<String, Object>> addCopiers(Context context, JSONArray copis) {
  479. List<Map<String, Object>> copiers = Lists.newArrayList();
  480. for (int i = 0; i < copis.size(); i++) {
  481. JSONObject cop = copis.getJSONObject(i);
  482. Map<String, Object> copierPsn = Maps.newHashMap();
  483. Map<String, Object> copierPsnInfo = Maps.newHashMap();
  484. copierPsnInfo.put("psnAccount", cop.getString("psnAccount"));
  485. copierPsn.put("copierPsnInfo", copierPsnInfo);
  486. copiers.add(copierPsn);
  487. }
  488. return copiers;
  489. }
  490. /**
  491. * 添加签署组织
  492. *
  493. * @param context
  494. * @param orgSignerInfo
  495. * @param docs
  496. * @param sourceId
  497. * @return
  498. * @throws EsignException
  499. * @throws URISyntaxException
  500. */
  501. public Map<String, Object> addOrgSignerInfo(Context context, JSONObject orgSignerInfo, List<Map<String, Object>> docs, String sourceId) throws EsignException, URISyntaxException {
  502. List< Map<String, Object>> resulList = Lists.newArrayList();
  503. Map<String, Object> resul = Maps.newHashMap();
  504. Map<String, Object> signMapInfo = Maps.newHashMap();
  505. Map<String, Object> orgPsnSignMap = Maps.newHashMap();
  506. String orgName = orgSignerInfo.getString("orgName");
  507. EsignHttpResponse response = EsignHttpUtil.getOrgIdentity_infoByOrgName(context, orgName);
  508. if (response.getStatus() >= 200 && response.getStatus() < 300) {
  509. JSONObject body = JSON.parseObject(response.getBody());
  510. if ("0".equals(String.valueOf(body.get("code")))) {
  511. JSONObject orgPsn = body.getJSONObject("data");
  512. String orgId = orgPsn.getString("orgId");
  513. orgName = orgPsn.getString("orgName");
  514. //自动落章只能传orgId
  515. if (true == orgSignerInfo.getBoolean("isRadio")) {
  516. orgPsnSignMap.put("orgId", orgId);
  517. } else {
  518. orgPsnSignMap.put("orgName", orgName);
  519. Map<String, Object> transactorInfo = Maps.newHashMap();
  520. transactorInfo.put("psnAccount", orgSignerInfo.getString("psnAccount"));
  521. Map<String, Object> psnInfo = Maps.newHashMap();
  522. psnInfo.put("psnName", orgSignerInfo.getString("psnName"));
  523. transactorInfo.put("psnInfo", psnInfo);
  524. orgPsnSignMap.put("transactorInfo", transactorInfo);
  525. orgPsnSignMap.put("orgInfo", orgPsn.getJSONObject("orgInfo"));
  526. }
  527. } else {
  528. //失败
  529. resul.putAll(body);
  530. throw new EsignException(JSON.toJSONString(resul));
  531. }
  532. } else {
  533. throw new EsignException("网络异常:" + JSON.toJSONString(response));
  534. }
  535. Integer signOrder = orgSignerInfo.getInteger("signOrder");
  536. //设置签署方的签署顺序
  537. if (null != signOrder) {
  538. Map<String, Object> signConfig = Maps.newHashMap();
  539. signConfig.put("signOrder", signOrder);
  540. signMapInfo.put("signConfig", signConfig);
  541. }
  542. signMapInfo.put("orgSignerInfo", orgPsnSignMap);
  543. //设置签署方的通知方式
  544. String noticeTypes = orgSignerInfo.getString("noticeTypes");
  545. Map<String, String> noticeConfig = Maps.newHashMap();
  546. if (StringUtils.isNotBlank(noticeTypes)) {
  547. noticeConfig.put("noticeTypes", noticeTypes);
  548. } else {
  549. noticeConfig.put("noticeTypes", "1,2");
  550. }
  551. signMapInfo.put("noticeConfig", noticeConfig);
  552. //签署区信息
  553. String signName = orgSignerInfo.getString("signName");
  554. if (StringUtils.isBlank(signName)) {
  555. signName = "签署方" + signOrder;
  556. }
  557. List<Map<String, Object>> signFields = Lists.newArrayList();
  558. for (Map<String, Object> doc : docs) {
  559. Map<String, List<Map<String, Object>>> signListGroup = (Map<String, List<Map<String, Object>>>) doc.get("signListGroup");
  560. //判断是否存在签署区
  561. if(null!=signListGroup && signListGroup.size()>0){
  562. List<Map<String, Object>> fieldList = signListGroup.get(signName);
  563. if(null!=fieldList) {
  564. for (Map<String, Object> fieldMap : fieldList) {
  565. Map<String, Object> field = Maps.newHashMap();
  566. field.put("fileId", fieldMap.get("fileId"));
  567. field.put("customBizNum", doc.get("fileName"));
  568. if (0 == ((int) fieldMap.get("signFieldType"))) {
  569. field.put("signFieldType", fieldMap.get("signFieldType"));
  570. //签章区配置项(指定signFieldType为 0 - 签章区时,该参数为必传项)
  571. Map<String, Object> normalSignFieldConfig = Maps.newHashMap();
  572. if (true == orgSignerInfo.getBoolean("isRadio")) {
  573. //企业/机构自动落章(autoSign为true),请不要传该参数。
  574. orgPsnSignMap.remove("transactorInfo");
  575. //自动落章
  576. normalSignFieldConfig.put("freeMode", false);
  577. normalSignFieldConfig.put("autoSign", true);
  578. //印章id
  579. normalSignFieldConfig.put("assignedSealId", orgSignerInfo.getString("sealId"));
  580. //印章类型:1印章,2骑缝章
  581. normalSignFieldConfig.put("signFieldStyle", fieldMap.get("signFieldStyle"));
  582. Map<String, Object> signFieldPosition = Maps.newHashMap();
  583. if (1 == ((int) fieldMap.get("signFieldStyle"))) {
  584. //正常章
  585. if (null != fieldMap.get("positionPage") && null != fieldMap.get("positionX") && null != fieldMap.get("positionY")) {
  586. signFieldPosition.put("positionPage", fieldMap.get("positionPage"));
  587. signFieldPosition.put("positionX", fieldMap.get("positionX"));
  588. signFieldPosition.put("positionY", fieldMap.get("positionY"));
  589. if (null != fieldMap.get("posX")) {
  590. signFieldPosition.put("positionX", fieldMap.get("posX"));
  591. }
  592. if (null != fieldMap.get("posY")) {
  593. signFieldPosition.put("positionY", fieldMap.get("posY"));
  594. }
  595. }
  596. } else {
  597. //骑缝章
  598. }
  599. normalSignFieldConfig.put("signFieldPosition", signFieldPosition);
  600. Map<String, Object> signDateConfig = Maps.newHashMap();
  601. signDateConfig.put("showSignDate", 1);
  602. field.put("signDateConfig", signDateConfig);
  603. } else {
  604. //手动签章
  605. normalSignFieldConfig.put("freeMode", true);
  606. normalSignFieldConfig.put("autoSign", false);
  607. }
  608. field.put("normalSignFieldConfig", normalSignFieldConfig);
  609. } else {
  610. field.put("signFieldType", fieldMap.get("signFieldType"));
  611. //签章区配置项(指定signFieldType为 0 - 签章区时,该参数为必传项)
  612. Map<String, Object> remarkSignFieldConfig = Maps.newHashMap();
  613. remarkSignFieldConfig.put("freeMode", true);
  614. remarkSignFieldConfig.put("inputType", 2);
  615. field.put("remarkSignFieldConfig", remarkSignFieldConfig);
  616. }
  617. signFields.add(field);
  618. }
  619. }
  620. else {
  621. Map<String, Object> res = Maps.newHashMap();
  622. //失败
  623. res.put("文件模板:"+doc.get("fileName"),signName+",未匹配到签署区,请检查模板的签署区命名规范。签署区命名规则:如(“甲方:(盖章)_签署方1_X50_Y50“)根据“_”分割字符串,第一个是要盖章的内容位置标识;第二个是签署方用来判断这个签署区是谁的;X50表示:印章位置向右移动50;Y50表示:印章位置向上移动50");
  624. resulList.add(res);
  625. }
  626. }
  627. }
  628. if(signFields.size()<=0) {
  629. throw new EsignException(JSON.toJSONString(resulList));
  630. }
  631. signMapInfo.put("signFields", signFields);
  632. signMapInfo.put("signerType", 1);
  633. return signMapInfo;
  634. }
  635. /**
  636. * 添加签署人
  637. *
  638. * @param context
  639. * @param psnSignerInfo
  640. * @param docs
  641. * @param sourceId
  642. * @return
  643. * @throws EsignException
  644. * @throws URISyntaxException
  645. */
  646. public Map<String, Object> addPsnSignerInfo(Context context, JSONObject psnSignerInfo, List<Map<String, Object>> docs, String sourceId) throws EsignException, URISyntaxException {
  647. List< Map<String, Object>> resulList = Lists.newArrayList();
  648. Map<String, Object> resul = Maps.newHashMap();
  649. Map<String, Object> signMapInfo = Maps.newHashMap();
  650. Map<String, Object> orgPsnSignMap = Maps.newHashMap();
  651. //个人签署方信息
  652. String psnAccount = psnSignerInfo.getString("psnAccount");
  653. String psnName = psnSignerInfo.getString("psnName");
  654. Integer signOrder = psnSignerInfo.getInteger("signOrder");
  655. //设置签署方的签署顺序
  656. if (null != signOrder) {
  657. Map<String, Object> signConfig = Maps.newHashMap();
  658. signConfig.put("signOrder", signOrder);
  659. signMapInfo.put("signConfig", signConfig);
  660. }
  661. orgPsnSignMap.put("psnAccount", psnAccount);
  662. Map<String, String> psnInfo = Maps.newHashMap();
  663. psnInfo.put("psnName", psnName);
  664. orgPsnSignMap.put("psnInfo", psnInfo);
  665. //个人签署方信息
  666. signMapInfo.put("psnSignerInfo", orgPsnSignMap);
  667. //设置签署方的通知方式
  668. String noticeTypes = psnSignerInfo.getString("noticeTypes");
  669. Map<String, String> noticeConfig = Maps.newHashMap();
  670. if (StringUtils.isNotBlank(noticeTypes)) {
  671. noticeConfig.put("noticeTypes", noticeTypes);
  672. } else {
  673. noticeConfig.put("noticeTypes", "1,2");
  674. }
  675. signMapInfo.put("noticeConfig", noticeConfig);
  676. //签署区信息
  677. List<Map<String, Object>> signFields = Lists.newArrayList();
  678. // for (Map<String, Object> doc : docs) {
  679. // Map<String, Object> field = Maps.newHashMap();
  680. // field.put("fileId", doc.get("fileId"));
  681. // field.put("customBizNum", sourceId);
  682. // field.put("signFieldType", 0);
  683. // //签章区配置项(指定signFieldType为 0 - 签章区时,该参数为必传项)
  684. // Map<String, Object> normalSignFieldConfig = Maps.newHashMap();
  685. // normalSignFieldConfig.put("freeMode", true);
  686. // normalSignFieldConfig.put("movableSignField", false);
  687. //
  688. // field.put("normalSignFieldConfig", normalSignFieldConfig);
  689. // signFields.add(field);
  690. // }
  691. //签署区信息
  692. String signName = psnSignerInfo.getString("signName");
  693. if (StringUtils.isBlank(signName)) {
  694. signName = "签署方" + signOrder;
  695. }
  696. for (Map<String, Object> doc : docs) {
  697. Map<String, List<Map<String, Object>>> signListGroup = (Map<String, List<Map<String, Object>>>) doc.get("signListGroup");
  698. List<Map<String, Object>> fieldList = signListGroup.get(signName);
  699. if(null!=fieldList) {
  700. for (Map<String, Object> fieldMap : fieldList) {
  701. Map<String, Object> field = Maps.newHashMap();
  702. field.put("fileId", fieldMap.get("fileId"));
  703. field.put("customBizNum", doc.get("fileName"));
  704. if (0 == ((int) fieldMap.get("signFieldType"))) {
  705. field.put("signFieldType", fieldMap.get("signFieldType"));
  706. //签章区配置项(指定signFieldType为 0 - 签章区时,该参数为必传项)
  707. Map<String, Object> normalSignFieldConfig = Maps.newHashMap();
  708. //手动签章
  709. normalSignFieldConfig.put("freeMode", true);
  710. normalSignFieldConfig.put("autoSign", false);
  711. //印章id
  712. //normalSignFieldConfig.put("assignedSealId", orgSignerInfo.getString("sealId"));
  713. //印章类型:1印章,2骑缝章
  714. normalSignFieldConfig.put("signFieldStyle", fieldMap.get("signFieldStyle"));
  715. Map<String, Object> signFieldPosition = Maps.newHashMap();
  716. if (1 == ((int) fieldMap.get("signFieldStyle"))) {
  717. //正常章
  718. if (null != fieldMap.get("positionPage") && null != fieldMap.get("positionX") && null != fieldMap.get("positionY")) {
  719. signFieldPosition.put("positionPage", fieldMap.get("positionPage"));
  720. signFieldPosition.put("positionX", fieldMap.get("positionX"));
  721. signFieldPosition.put("positionY", fieldMap.get("positionY"));
  722. if (null != fieldMap.get("posX")) {
  723. signFieldPosition.put("positionX", fieldMap.get("posX"));
  724. }
  725. if (null != fieldMap.get("posY")) {
  726. signFieldPosition.put("positionY", fieldMap.get("posY"));
  727. }
  728. }
  729. } else {
  730. //骑缝章
  731. }
  732. normalSignFieldConfig.put("signFieldPosition", signFieldPosition);
  733. Map<String, Object> signDateConfig = Maps.newHashMap();
  734. signDateConfig.put("showSignDate", 1);
  735. field.put("signDateConfig", signDateConfig);
  736. field.put("normalSignFieldConfig", normalSignFieldConfig);
  737. } else {
  738. field.put("signFieldType", fieldMap.get("signFieldType"));
  739. //签章区配置项(指定signFieldType为 0 - 签章区时,该参数为必传项)
  740. Map<String, Object> remarkSignFieldConfig = Maps.newHashMap();
  741. remarkSignFieldConfig.put("freeMode", true);
  742. remarkSignFieldConfig.put("inputType", 2);
  743. field.put("remarkSignFieldConfig", remarkSignFieldConfig);
  744. }
  745. signFields.add(field);
  746. }
  747. } else {
  748. Map<String, Object> res = Maps.newHashMap();
  749. //失败
  750. res.put("文件模板:"+doc.get("fileName"),signName+",未匹配到签署区,请检查模板的签署区命名规范。签署区命名规则:如(“甲方:(盖章)_签署方1_X50_Y50“)根据“_”分割字符串,第一个是要盖章的内容位置标识;第二个是签署方用来判断这个签署区是谁的;X50表示:印章位置向右移动50;Y50表示:印章位置向上移动50");
  751. resulList.add(res);
  752. }
  753. }
  754. if(signFields.size()<=0) {
  755. throw new EsignException(JSON.toJSONString(resulList));
  756. }
  757. signMapInfo.put("signFields", signFields);
  758. signMapInfo.put("signerType", 0);
  759. return signMapInfo;
  760. }
  761. /**
  762. * 处理签署方信息
  763. *
  764. * @param context
  765. * @param signs
  766. * @param docs
  767. * @param sourceId
  768. * @return
  769. * @throws EsignException
  770. * @throws URISyntaxException
  771. */
  772. public List<Map<String, Object>> addSigners(Context context, JSONArray signs, List<Map<String, Object>> docs, String sourceId) throws EsignException, URISyntaxException {
  773. List<Map<String, Object>> signers = Lists.newArrayList();
  774. for (int i = 0; i < signs.size(); i++) {
  775. Map<String, Object> signMapInfo = Maps.newHashMap();
  776. JSONObject sign = signs.getJSONObject(i);
  777. Map<String, Object> orgPsnSignMap = Maps.newHashMap();
  778. JSONObject orgSignerInfo = sign.getJSONObject("orgSignerInfo");
  779. JSONObject psnSignerInfo = sign.getJSONObject("psnSignerInfo");
  780. //企业/机构签署方信息
  781. if (null != orgSignerInfo) {
  782. signMapInfo = addOrgSignerInfo(context, orgSignerInfo, docs, sourceId);
  783. } else {
  784. //个人签署方信息
  785. signMapInfo = addPsnSignerInfo(context, psnSignerInfo, docs, sourceId);
  786. }
  787. signers.add(signMapInfo);
  788. }
  789. return signers;
  790. }
  791. /**
  792. * 签署流程配置项
  793. *
  794. * @param context
  795. * @param signFlowTitle
  796. * @param jsonObject
  797. * @return
  798. */
  799. public Map<String, Object> addSignFlowConfig(Context context, String signFlowTitle, JSONObject jsonObject) {
  800. Map<String, Object> signFlowConfig = Maps.newHashMap();
  801. signFlowConfig.put("signFlowTitle", signFlowTitle);
  802. Boolean autoStart = jsonObject.getBoolean("autoStart");
  803. if (null != autoStart) {
  804. signFlowConfig.put("autoStart", autoStart);
  805. } else {
  806. signFlowConfig.put("autoStart", true);
  807. }
  808. Boolean autoFinish = jsonObject.getBoolean("autoFinish");
  809. if (null != autoFinish) {
  810. signFlowConfig.put("autoFinish", autoFinish);
  811. } else {
  812. signFlowConfig.put("autoFinish", true);
  813. }
  814. String notifyUrl = jsonObject.getString("notifyUrl");
  815. if (null != notifyUrl) {
  816. signFlowConfig.put("notifyUrl", notifyUrl);
  817. } else {
  818. notifyUrl = EsignConfig.getInstance().get("notifyUrl");
  819. signFlowConfig.put("notifyUrl", notifyUrl);
  820. }
  821. return signFlowConfig;
  822. }
  823. /**
  824. * 根据传入数据调用 ”填写模板生成文件“ 接口
  825. *
  826. * @param jsonObject
  827. * @return
  828. */
  829. public EsignHttpResponse previewFile(Context context, JSONObject jsonObject, String sourceId) throws EsignException {
  830. String docTemplateId = jsonObject.getString("id");
  831. String fileName = jsonObject.getString("name");
  832. if (StringUtils.isBlank(docTemplateId)) {
  833. docTemplateId = jsonObject.getString("tableId");
  834. }
  835. if (StringUtils.isBlank(fileName)) {
  836. fileName = jsonObject.getString("tableName");
  837. }
  838. Map<String, Object> map = Maps.newHashMap();
  839. map.put("docTemplateId", docTemplateId);
  840. map.put("fileName", fileName);
  841. List<Map<String, Object>> components = Lists.newArrayList();
  842. JSONObject fields = jsonObject.getJSONObject("fields");
  843. for (Map.Entry<String, Object> field : fields.entrySet()) {
  844. Map<String, Object> component = Maps.newHashMap();
  845. component.put("componentId", field.getKey());
  846. JSONObject fieldInfo = (JSONObject) field.getValue();
  847. String dataType = (String) fieldInfo.get("dataType");
  848. if (ComponentTypeEnum.SIGN_AREA.getAlias().equals(dataType)) {
  849. continue;
  850. }
  851. component.put("componentValue", fieldInfo.get("value"));
  852. components.add(component);
  853. }
  854. map.put("components", components);
  855. EsignHttpResponse response = EsignHttpUtil.createByDocTemplate(context, JSON.toJSONString(map), sourceId);
  856. return response;
  857. }
  858. }