Create_by_fileOSFService.java 42 KB

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