Create_by_fileOSFService.java 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921
  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. if (StringUtils.isBlank(docTemplateId)) {
  414. docTemplateId = fieldObject.getString("tableId");
  415. }
  416. if (StringUtils.isBlank(fileName)) {
  417. fileName = fieldObject.getString("tableName");
  418. }
  419. Object order = fieldObject.get("order");
  420. String sourceId = jsonObject.getString("sourceId");
  421. EsignHttpResponse response = this.previewFile(context, fieldObject, sourceId);
  422. resul.put("id", docTemplateId);
  423. resul.put("name", fileName);
  424. if (response.getStatus() >= 200 && response.getStatus() < 300) {
  425. Map<String, Object> body = this.processFileResponse(response, context);
  426. if ("0".equals(String.valueOf(body.get("code")))) {
  427. JSONObject file = (JSONObject) body.get("data");
  428. Map<String, Object> doc = Maps.newHashMap();
  429. doc.put("fileId", file.get("fileId"));
  430. doc.put("fileName", fileName);
  431. if (null != order) {
  432. doc.put("order", Integer.parseInt(String.valueOf(order)));
  433. }
  434. System.out.println("addDocs:" + fieldObject);
  435. JSONObject fields = fieldObject.getJSONObject("fields");
  436. //取得这个文件的签署人的签署区
  437. Map<String, Map<String, Map<String, Object>>> signAreaList = this.addsignAreaList(context, fields, (String) file.get("fileId"), sourceId,docTemplateId);
  438. doc.put("signListGroup", signAreaList);
  439. docs.add(doc);
  440. } else {
  441. //文件模板生成失败
  442. resul.putAll(body);
  443. throw new EsignException(JSON.toJSONString(resul));
  444. }
  445. } else {
  446. throw new EsignException(JSON.toJSONString(response));
  447. }
  448. }
  449. return docs;
  450. }
  451. /**
  452. * 抄送方信息
  453. *
  454. * @param copis
  455. * @return
  456. */
  457. public List<Map<String, Object>> addCopiers(Context context, JSONArray copis) {
  458. List<Map<String, Object>> copiers = Lists.newArrayList();
  459. for (int i = 0; i < copis.size(); i++) {
  460. JSONObject cop = copis.getJSONObject(i);
  461. Map<String, Object> copierPsn = Maps.newHashMap();
  462. Map<String, Object> copierPsnInfo = Maps.newHashMap();
  463. copierPsnInfo.put("psnAccount", cop.getString("psnAccount"));
  464. copierPsn.put("copierPsnInfo", copierPsnInfo);
  465. copiers.add(copierPsn);
  466. }
  467. return copiers;
  468. }
  469. /**
  470. * 添加签署组织
  471. *
  472. * @param context
  473. * @param orgSignerInfo
  474. * @param docs
  475. * @param sourceId
  476. * @return
  477. * @throws EsignException
  478. * @throws URISyntaxException
  479. */
  480. public Map<String, Object> addOrgSignerInfo(Context context, JSONObject orgSignerInfo, List<Map<String, Object>> docs, String sourceId) throws EsignException, URISyntaxException {
  481. List<Map<String, Object>> resulList = Lists.newArrayList();
  482. List<Map<String, Object>> resulErrList = Lists.newArrayList();
  483. Map<String, Object> resul = Maps.newHashMap();
  484. Map<String, Object> signMapInfo = Maps.newHashMap();
  485. Map<String, Object> orgPsnSignMap = Maps.newHashMap();
  486. String orgName = orgSignerInfo.getString("orgName");
  487. EsignHttpResponse response = EsignHttpUtil.getOrgIdentity_infoByOrgName(context, orgName);
  488. if (response.getStatus() >= 200 && response.getStatus() < 300) {
  489. JSONObject body = JSON.parseObject(response.getBody());
  490. if ("0".equals(String.valueOf(body.get("code")))) {
  491. JSONObject orgPsn = body.getJSONObject("data");
  492. String orgId = orgPsn.getString("orgId");
  493. orgName = orgPsn.getString("orgName");
  494. //自动落章只能传orgId
  495. if (true == orgSignerInfo.getBoolean("isRadio")) {
  496. orgPsnSignMap.put("orgId", orgId);
  497. } else {
  498. orgPsnSignMap.put("orgName", orgName);
  499. Map<String, Object> transactorInfo = Maps.newHashMap();
  500. transactorInfo.put("psnAccount", orgSignerInfo.getString("psnAccount"));
  501. Map<String, Object> psnInfo = Maps.newHashMap();
  502. psnInfo.put("psnName", orgSignerInfo.getString("psnName"));
  503. transactorInfo.put("psnInfo", psnInfo);
  504. orgPsnSignMap.put("transactorInfo", transactorInfo);
  505. orgPsnSignMap.put("orgInfo", orgPsn.getJSONObject("orgInfo"));
  506. }
  507. } else {
  508. //失败
  509. resul.putAll(body);
  510. throw new EsignException(JSON.toJSONString(resul));
  511. }
  512. } else {
  513. throw new EsignException("网络异常:" + JSON.toJSONString(response));
  514. }
  515. Integer signOrder = orgSignerInfo.getInteger("signOrder");
  516. //设置签署方的签署顺序
  517. if (null != signOrder) {
  518. Map<String, Object> signConfig = Maps.newHashMap();
  519. signConfig.put("signOrder", signOrder);
  520. signMapInfo.put("signConfig", signConfig);
  521. }
  522. signMapInfo.put("orgSignerInfo", orgPsnSignMap);
  523. //设置签署方的通知方式
  524. String noticeTypes = orgSignerInfo.getString("noticeTypes");
  525. Map<String, String> noticeConfig = Maps.newHashMap();
  526. if (StringUtils.isNotBlank(noticeTypes)) {
  527. noticeConfig.put("noticeTypes", noticeTypes);
  528. } else {
  529. noticeConfig.put("noticeTypes", "1,2");
  530. }
  531. signMapInfo.put("noticeConfig", noticeConfig);
  532. //签署区信息
  533. String signName = orgSignerInfo.getString("signName");
  534. if (StringUtils.isBlank(signName)) {
  535. signName = "签署方" + signOrder;
  536. }
  537. List<Map<String, Object>> signFields = Lists.newArrayList();
  538. for (Map<String, Object> doc : docs) {
  539. Map<String, Map<String, Map<String, Object>>> signListGroup = (Map<String,Map<String, Map<String, Object>>>) doc.get("signListGroup");
  540. //判断是否存在签署区
  541. if(null!=signListGroup && signListGroup.size()>0){
  542. Map<String, Map<String, Object>> fieldList = signListGroup.get(signName);
  543. if(null!=fieldList) {
  544. for (Map<String, Object> fieldMap : fieldList.values()) {
  545. Map<String, Object> field = Maps.newHashMap();
  546. field.put("fileId", fieldMap.get("fileId"));
  547. field.put("customBizNum", doc.get("fileName"));
  548. if (0 == ((int) fieldMap.get("signFieldType"))) {
  549. field.put("signFieldType", fieldMap.get("signFieldType"));
  550. //签章区配置项(指定signFieldType为 0 - 签章区时,该参数为必传项)
  551. Map<String, Object> normalSignFieldConfig = Maps.newHashMap();
  552. if (true == orgSignerInfo.getBoolean("isRadio")) {
  553. //企业/机构自动落章(autoSign为true),请不要传该参数。
  554. orgPsnSignMap.remove("transactorInfo");
  555. //自动落章
  556. normalSignFieldConfig.put("freeMode", false);
  557. normalSignFieldConfig.put("autoSign", true);
  558. //印章id
  559. normalSignFieldConfig.put("assignedSealId", orgSignerInfo.getString("sealId"));
  560. //印章类型:1印章,2骑缝章
  561. normalSignFieldConfig.put("signFieldStyle", fieldMap.get("signFieldStyle"));
  562. Map<String, Object> signFieldPosition = Maps.newHashMap();
  563. if (1 == ((int) fieldMap.get("signFieldStyle"))) {
  564. //正常章
  565. if (null != fieldMap.get("positionPage") && null != fieldMap.get("positionX") && null != fieldMap.get("positionY")) {
  566. signFieldPosition.put("positionPage", fieldMap.get("positionPage"));
  567. signFieldPosition.put("positionX", fieldMap.get("positionX"));
  568. signFieldPosition.put("positionY", fieldMap.get("positionY"));
  569. } else {
  570. Map<String, Object> res = Maps.newHashMap();
  571. //失败
  572. res.put("文件模板:"+doc.get("fileName"),signName+",未匹配到签署区,请检查模板的签署区命名规范。签署区命名规则:如(“甲方:(盖章)_签署方1_X50_Y50“)根据“_”分割字符串,第一个是要盖章的内容位置标识;第二个是签署方用来判断这个签署区是谁的;X50表示:印章位置向右移动50;Y50表示:印章位置向上移动50");
  573. resulErrList.add(res);
  574. }
  575. } else {
  576. //骑缝章
  577. signFieldPosition.put("positionY", fieldMap.get("positionY"));
  578. }
  579. normalSignFieldConfig.put("signFieldPosition", signFieldPosition);
  580. Map<String, Object> signDateConfig = (Map<String, Object>) fieldMap.get("signDateConfig");
  581. if(null==signDateConfig) {
  582. signDateConfig = Maps.newHashMap();
  583. //signDateConfig.put("showSignDate", 1);
  584. }
  585. field.put("signDateConfig", signDateConfig);
  586. } else {
  587. //手动签章
  588. normalSignFieldConfig.put("freeMode", false);
  589. normalSignFieldConfig.put("autoSign", false);
  590. //印章id
  591. normalSignFieldConfig.put("assignedSealId", orgSignerInfo.getString("sealId"));
  592. //印章类型:1印章,2骑缝章
  593. normalSignFieldConfig.put("signFieldStyle", fieldMap.get("signFieldStyle"));
  594. Map<String, Object> signFieldPosition = Maps.newHashMap();
  595. if (1 == ((int) fieldMap.get("signFieldStyle"))) {
  596. //正常章
  597. if (null != fieldMap.get("positionPage") && null != fieldMap.get("positionX") && null != fieldMap.get("positionY")) {
  598. signFieldPosition.put("positionPage", fieldMap.get("positionPage"));
  599. signFieldPosition.put("positionX", fieldMap.get("positionX"));
  600. signFieldPosition.put("positionY", fieldMap.get("positionY"));
  601. } else {
  602. Map<String, Object> res = Maps.newHashMap();
  603. //失败
  604. res.put("文件模板:"+doc.get("fileName"),signName+",未匹配到签署区,请检查模板的签署区命名规范。签署区命名规则:如(“甲方:(盖章)_签署方1_X50_Y50“)根据“_”分割字符串,第一个是要盖章的内容位置标识;第二个是签署方用来判断这个签署区是谁的;X50表示:印章位置向右移动50;Y50表示:印章位置向上移动50");
  605. resulErrList.add(res);
  606. }
  607. } else {
  608. //骑缝章
  609. signFieldPosition.put("positionY", fieldMap.get("positionY"));
  610. }
  611. normalSignFieldConfig.put("signFieldPosition", signFieldPosition);
  612. Map<String, Object> signDateConfig = (Map<String, Object>) fieldMap.get("signDateConfig");
  613. if(null==signDateConfig) {
  614. signDateConfig = Maps.newHashMap();
  615. //signDateConfig.put("showSignDate", 1);
  616. }
  617. field.put("signDateConfig", signDateConfig);
  618. }
  619. field.put("normalSignFieldConfig", normalSignFieldConfig);
  620. } else {
  621. field.put("signFieldType", fieldMap.get("signFieldType"));
  622. //签章区配置项(指定signFieldType为 0 - 签章区时,该参数为必传项)
  623. Map<String, Object> remarkSignFieldConfig = Maps.newHashMap();
  624. remarkSignFieldConfig.put("freeMode", true);
  625. remarkSignFieldConfig.put("inputType", 2);
  626. field.put("remarkSignFieldConfig", remarkSignFieldConfig);
  627. }
  628. signFields.add(field);
  629. }
  630. }
  631. else {
  632. Map<String, Object> res = Maps.newHashMap();
  633. //失败
  634. res.put("文件模板:"+doc.get("fileName"),signName+",未匹配到签署区,请检查模板的签署区命名规范。签署区命名规则:如(“甲方:(盖章)_签署方1_X50_Y50“)根据“_”分割字符串,第一个是要盖章的内容位置标识;第二个是签署方用来判断这个签署区是谁的;X50表示:印章位置向右移动50;Y50表示:印章位置向上移动50");
  635. resulList.add(res);
  636. }
  637. }
  638. }
  639. if(signFields.size()<=0) {
  640. throw new EsignException(JSON.toJSONString(resulList));
  641. }
  642. if(resulErrList.size()>0) {
  643. throw new EsignException(JSON.toJSONString(resulErrList));
  644. }
  645. signMapInfo.put("signFields", signFields);
  646. signMapInfo.put("signerType", 1);
  647. return signMapInfo;
  648. }
  649. /**
  650. * 添加签署人
  651. *
  652. * @param context
  653. * @param psnSignerInfo
  654. * @param docs
  655. * @param sourceId
  656. * @return
  657. * @throws EsignException
  658. * @throws URISyntaxException
  659. */
  660. public Map<String, Object> addPsnSignerInfo(Context context, JSONObject psnSignerInfo, List<Map<String, Object>> docs, String sourceId) throws EsignException, URISyntaxException {
  661. List< Map<String, Object>> resulList = Lists.newArrayList();
  662. Map<String, Object> resul = Maps.newHashMap();
  663. Map<String, Object> signMapInfo = Maps.newHashMap();
  664. Map<String, Object> orgPsnSignMap = Maps.newHashMap();
  665. //个人签署方信息
  666. String psnAccount = psnSignerInfo.getString("psnAccount");
  667. String psnName = psnSignerInfo.getString("psnName");
  668. Integer signOrder = psnSignerInfo.getInteger("signOrder");
  669. //设置签署方的签署顺序
  670. if (null != signOrder) {
  671. Map<String, Object> signConfig = Maps.newHashMap();
  672. signConfig.put("signOrder", signOrder);
  673. signMapInfo.put("signConfig", signConfig);
  674. }
  675. orgPsnSignMap.put("psnAccount", psnAccount);
  676. Map<String, String> psnInfo = Maps.newHashMap();
  677. psnInfo.put("psnName", psnName);
  678. orgPsnSignMap.put("psnInfo", psnInfo);
  679. //个人签署方信息
  680. signMapInfo.put("psnSignerInfo", orgPsnSignMap);
  681. //设置签署方的通知方式
  682. String noticeTypes = psnSignerInfo.getString("noticeTypes");
  683. Map<String, String> noticeConfig = Maps.newHashMap();
  684. if (StringUtils.isNotBlank(noticeTypes)) {
  685. noticeConfig.put("noticeTypes", noticeTypes);
  686. } else {
  687. noticeConfig.put("noticeTypes", "1,2");
  688. }
  689. signMapInfo.put("noticeConfig", noticeConfig);
  690. //签署区信息
  691. List<Map<String, Object>> signFields = Lists.newArrayList();
  692. // for (Map<String, Object> doc : docs) {
  693. // Map<String, Object> field = Maps.newHashMap();
  694. // field.put("fileId", doc.get("fileId"));
  695. // field.put("customBizNum", sourceId);
  696. // field.put("signFieldType", 0);
  697. // //签章区配置项(指定signFieldType为 0 - 签章区时,该参数为必传项)
  698. // Map<String, Object> normalSignFieldConfig = Maps.newHashMap();
  699. // normalSignFieldConfig.put("freeMode", true);
  700. // normalSignFieldConfig.put("movableSignField", false);
  701. //
  702. // field.put("normalSignFieldConfig", normalSignFieldConfig);
  703. // signFields.add(field);
  704. // }
  705. //签署区信息
  706. String signName = psnSignerInfo.getString("signName");
  707. if (StringUtils.isBlank(signName)) {
  708. signName = "签署方" + signOrder;
  709. }
  710. for (Map<String, Object> doc : docs) {
  711. Map<String, Map<String, Map<String, Object>>> signListGroup = (Map<String, Map<String, Map<String, Object>>>) doc.get("signListGroup");
  712. Map<String, Map<String, Object>> fieldList = signListGroup.get(signName);
  713. if(null!=fieldList) {
  714. for (Map<String, Object> fieldMap : fieldList.values()) {
  715. Map<String, Object> field = Maps.newHashMap();
  716. field.put("fileId", fieldMap.get("fileId"));
  717. field.put("customBizNum", doc.get("fileName"));
  718. if (0 == ((int) fieldMap.get("signFieldType"))) {
  719. field.put("signFieldType", fieldMap.get("signFieldType"));
  720. //签章区配置项(指定signFieldType为 0 - 签章区时,该参数为必传项)
  721. Map<String, Object> normalSignFieldConfig = Maps.newHashMap();
  722. //手动签章
  723. normalSignFieldConfig.put("freeMode", false);
  724. normalSignFieldConfig.put("autoSign", false);
  725. //印章id
  726. //normalSignFieldConfig.put("assignedSealId", orgSignerInfo.getString("sealId"));
  727. //印章类型:1印章,2骑缝章
  728. normalSignFieldConfig.put("signFieldStyle", fieldMap.get("signFieldStyle"));
  729. Map<String, Object> signFieldPosition = Maps.newHashMap();
  730. if (1 == ((int) fieldMap.get("signFieldStyle"))) {
  731. //正常章
  732. if (null != fieldMap.get("positionPage") && null != fieldMap.get("positionX") && null != fieldMap.get("positionY")) {
  733. signFieldPosition.put("positionPage", fieldMap.get("positionPage"));
  734. signFieldPosition.put("positionX", fieldMap.get("positionX"));
  735. signFieldPosition.put("positionY", fieldMap.get("positionY"));
  736. }
  737. } else {
  738. //骑缝章
  739. signFieldPosition.put("positionY", fieldMap.get("positionY"));
  740. }
  741. normalSignFieldConfig.put("signFieldPosition", signFieldPosition);
  742. Map<String, Object> signDateConfig = (Map<String, Object>) fieldMap.get("signDateConfig");
  743. if(null==signDateConfig) {
  744. signDateConfig = Maps.newHashMap();
  745. signDateConfig.put("showSignDate", 1);
  746. }
  747. field.put("signDateConfig", signDateConfig);
  748. field.put("normalSignFieldConfig", normalSignFieldConfig);
  749. } else {
  750. field.put("signFieldType", fieldMap.get("signFieldType"));
  751. //签章区配置项(指定signFieldType为 0 - 签章区时,该参数为必传项)
  752. Map<String, Object> remarkSignFieldConfig = Maps.newHashMap();
  753. remarkSignFieldConfig.put("freeMode", true);
  754. remarkSignFieldConfig.put("inputType", 2);
  755. field.put("remarkSignFieldConfig", remarkSignFieldConfig);
  756. }
  757. signFields.add(field);
  758. }
  759. } else {
  760. Map<String, Object> res = Maps.newHashMap();
  761. //失败
  762. res.put("文件模板:"+doc.get("fileName"),signName+",未匹配到签署区,请检查模板的签署区命名规范。签署区命名规则:如(“甲方:(盖章)_签署方1_X50_Y50“)根据“_”分割字符串,第一个是要盖章的内容位置标识;第二个是签署方用来判断这个签署区是谁的;X50表示:印章位置向右移动50;Y50表示:印章位置向上移动50");
  763. resulList.add(res);
  764. }
  765. }
  766. if(signFields.size()<=0) {
  767. throw new EsignException(JSON.toJSONString(resulList));
  768. }
  769. signMapInfo.put("signFields", signFields);
  770. signMapInfo.put("signerType", 0);
  771. return signMapInfo;
  772. }
  773. /**
  774. * 处理签署方信息
  775. *
  776. * @param context
  777. * @param signs
  778. * @param docs
  779. * @param sourceId
  780. * @return
  781. * @throws EsignException
  782. * @throws URISyntaxException
  783. */
  784. public List<Map<String, Object>> addSigners(Context context, JSONArray signs, List<Map<String, Object>> docs, String sourceId) throws EsignException, URISyntaxException {
  785. List<Map<String, Object>> signers = Lists.newArrayList();
  786. for (int i = 0; i < signs.size(); i++) {
  787. Map<String, Object> signMapInfo = Maps.newHashMap();
  788. JSONObject sign = signs.getJSONObject(i);
  789. Map<String, Object> orgPsnSignMap = Maps.newHashMap();
  790. JSONObject orgSignerInfo = sign.getJSONObject("orgSignerInfo");
  791. JSONObject psnSignerInfo = sign.getJSONObject("psnSignerInfo");
  792. //企业/机构签署方信息
  793. if (null != orgSignerInfo) {
  794. signMapInfo = addOrgSignerInfo(context, orgSignerInfo, docs, sourceId);
  795. } else {
  796. //个人签署方信息
  797. signMapInfo = addPsnSignerInfo(context, psnSignerInfo, docs, sourceId);
  798. }
  799. signers.add(signMapInfo);
  800. }
  801. return signers;
  802. }
  803. /**
  804. * 签署流程配置项
  805. *
  806. * @param context
  807. * @param signFlowTitle
  808. * @param jsonObject
  809. * @return
  810. */
  811. public Map<String, Object> addSignFlowConfig(Context context, String signFlowTitle, JSONObject jsonObject) {
  812. Map<String, Object> signFlowConfig = Maps.newHashMap();
  813. signFlowConfig.put("signFlowTitle", signFlowTitle);
  814. Boolean autoStart = jsonObject.getBoolean("autoStart");
  815. if (null != autoStart) {
  816. signFlowConfig.put("autoStart", autoStart);
  817. } else {
  818. signFlowConfig.put("autoStart", true);
  819. }
  820. Boolean autoFinish = jsonObject.getBoolean("autoFinish");
  821. if (null != autoFinish) {
  822. signFlowConfig.put("autoFinish", autoFinish);
  823. } else {
  824. signFlowConfig.put("autoFinish", true);
  825. }
  826. String notifyUrl = jsonObject.getString("notifyUrl");
  827. if (null != notifyUrl) {
  828. signFlowConfig.put("notifyUrl", notifyUrl);
  829. } else {
  830. notifyUrl = EsignConfig.getInstance().get("notifyUrl");
  831. signFlowConfig.put("notifyUrl", notifyUrl);
  832. }
  833. return signFlowConfig;
  834. }
  835. /**
  836. * 根据传入数据调用 ”填写模板生成文件“ 接口
  837. *
  838. * @param jsonObject
  839. * @return
  840. */
  841. public EsignHttpResponse previewFile(Context context, JSONObject jsonObject, String sourceId) throws EsignException {
  842. String docTemplateId = jsonObject.getString("id");
  843. String fileName = jsonObject.getString("name");
  844. if (StringUtils.isBlank(docTemplateId)) {
  845. docTemplateId = jsonObject.getString("tableId");
  846. }
  847. if (StringUtils.isBlank(fileName)) {
  848. fileName = jsonObject.getString("tableName");
  849. }
  850. Map<String, Object> map = Maps.newHashMap();
  851. map.put("docTemplateId", docTemplateId);
  852. map.put("fileName", fileName);
  853. List<Map<String, Object>> components = Lists.newArrayList();
  854. JSONObject fields = jsonObject.getJSONObject("fields");
  855. for (Map.Entry<String, Object> field : fields.entrySet()) {
  856. Map<String, Object> component = Maps.newHashMap();
  857. component.put("componentId", field.getKey());
  858. JSONObject fieldInfo = (JSONObject) field.getValue();
  859. String dataType = (String) fieldInfo.get("dataType");
  860. if (ComponentTypeEnum.SIGN_AREA.getAlias().equals(dataType)) {
  861. continue;
  862. }
  863. if (ComponentTypeEnum.DATESIGNATURE.getAlias().equals(dataType)) {
  864. continue;
  865. }
  866. if (null==fieldInfo.get("value")) {
  867. continue;
  868. }
  869. component.put("componentValue", fieldInfo.get("value"));
  870. components.add(component);
  871. }
  872. map.put("components", components);
  873. EsignHttpResponse response = EsignHttpUtil.createByDocTemplate(context, JSON.toJSONString(map), sourceId);
  874. return response;
  875. }
  876. }