GetESignConfigDataService.java 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. package com.kingdee.eas.custom.esign.service;
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.kingdee.bos.BOSException;
  4. import com.kingdee.bos.Context;
  5. import com.kingdee.bos.bsf.service.app.IHRMsfService;
  6. import com.kingdee.bos.metadata.access.Simple;
  7. import com.kingdee.bos.metadata.entity.EntityViewInfo;
  8. import com.kingdee.bos.metadata.entity.FilterInfo;
  9. import com.kingdee.bos.metadata.entity.FilterItemInfo;
  10. import com.kingdee.bos.metadata.entity.SelectorItemCollection;
  11. import com.kingdee.bos.metadata.query.util.CompareType;
  12. import com.kingdee.bos.sql.ParserException;
  13. import com.kingdee.bos.util.BOSUuid;
  14. import com.kingdee.eas.common.EASBizException;
  15. import com.kingdee.eas.custom.dataconfig.utils.SqlUtils;
  16. import com.kingdee.eas.custom.entryconfig.DataConfigInfo;
  17. import com.kingdee.eas.custom.entryconfig.DataConfigSelectFieldEntryCollection;
  18. import com.kingdee.eas.custom.entryconfig.DataConfigSelectFieldEntryInfo;
  19. import com.kingdee.eas.custom.esign.*;
  20. import com.kingdee.eas.custom.esign.bizEnum.ComponentTypeEnum;
  21. import com.kingdee.eas.custom.esign.utils.ESignFieldMappingUtils;
  22. import com.kingdee.eas.fi.arap.util.DBUtil;
  23. import com.kingdee.jdbc.rowset.IRowSet;
  24. import com.kingdee.util.enums.Enum;
  25. import java.sql.SQLException;
  26. import java.text.SimpleDateFormat;
  27. import java.util.Map;
  28. import java.util.logging.SimpleFormatter;
  29. /**
  30. * 获取电子签配置数据的服务类
  31. * 实现IHRMsfService接口,用于处理电子签配置数据的查询与封装
  32. */
  33. public class GetESignConfigDataService implements IHRMsfService {
  34. /**
  35. * 处理请求的核心方法
  36. * @param context 上下文对象,包含环境信息
  37. * @param map 参数映射,包含请求的参数
  38. * @return 处理后的电子签配置数据,以JSONObject形式返回
  39. * @throws EASBizException EAS业务异常
  40. * @throws BOSException BOS框架异常
  41. */
  42. @Override
  43. public Object process(Context context, Map map) throws EASBizException, BOSException {
  44. // 从参数映射中获取"number"参数值,用于定位配置信息
  45. Object o = map.get("number");
  46. // 从参数映射中获取"filter"参数值,用于构建查询过滤条件
  47. Object o1 = map.get("filter");
  48. // 若"number"参数为null,返回空字符串(无效请求)
  49. if(o==null){
  50. return "";
  51. }
  52. // 将"number"参数转换为字符串类型
  53. String number = o.toString();
  54. // 将"filter"参数转换为字符串类型(若为null则转换为"null"字符串)
  55. String filter = o1.toString();
  56. // 声明实体视图信息对象,用于查询时的字段映射配置
  57. EntityViewInfo entityViewInfo= null;
  58. try {
  59. // 调用方法获取实体视图信息,该视图包含查询所需的字段映射配置
  60. entityViewInfo = this.getEntityViewInfo(number);
  61. } catch (ParserException e) {
  62. // 解析异常时,封装为运行时异常抛出
  63. throw new RuntimeException(e);
  64. }
  65. // 通过字段映射工厂,根据实体视图信息查询对应的字段映射集合
  66. FieldMappingCollection fieldMappingCollection = FieldMappingFactory.
  67. getLocalInstance(context).getFieldMappingCollection(entityViewInfo);
  68. // 创建SQL工具类实例,用于SQL语句的构建辅助
  69. SqlUtils sqlUtils = new SqlUtils();
  70. // 创建电子签字段映射工具类实例,用于字段映射的核心处理
  71. ESignFieldMappingUtils utils = new ESignFieldMappingUtils();
  72. // 获取字段映射集合中的第一个映射信息(默认取第一个配置项)
  73. FieldMappingInfo fieldMappingInfo = fieldMappingCollection.get(0);
  74. // 获取当前字段映射信息中的明细项集合(包含具体的字段映射关系)
  75. FieldMappingEntryCollection entrys = fieldMappingInfo.getEntrys();
  76. // 获取当前字段映射信息对应的数据源配置
  77. DataConfigInfo dataSource = fieldMappingInfo.getDataSource();
  78. // 验证数据源配置是否有效(非空且编号存在)
  79. if (dataSource!=null&&dataSource.getNumber()!=null&&!dataSource.getNumber().equals("")){
  80. // 通过工具类从字段映射明细中获取电子签SQL所需的字段集合
  81. DataConfigSelectFieldEntryCollection eSignSqlField = utils.getESignSqlField(entrys);
  82. // 创建字符串构建器,用于拼接SQL查询的字段部分
  83. StringBuilder sqlField = new StringBuilder();
  84. // 调用SQL工具类,将电子签字段集合拼接为SQL的SELECT子句
  85. sqlUtils.getSelectField(eSignSqlField, sqlField);
  86. // 获取数据源配置的编号
  87. String number1 = dataSource.getNumber();
  88. // 获取当前字段映射信息对应的电子签模板信息
  89. ESignTemplateInfo eSignFile = fieldMappingInfo.getESignFile();
  90. String eSignTemplateNum = eSignFile.getESignTemplateNum();
  91. if(sqlField.toString().equals("")){
  92. JSONObject jsonObject = this.reassembleData(eSignFile, eSignTemplateNum,context);
  93. return jsonObject;
  94. }
  95. // 通过工具类根据数据源编号和上下文获取电子签基础查询SQL
  96. String eSignSql = utils.getESignSql(number1, context);
  97. // 替换SQL中的{{filed}}占位符为实际拼接的查询字段
  98. eSignSql = eSignSql.replace("{{filed}}",sqlField.toString());
  99. // 在SQL末尾添加过滤条件(换行分隔,便于阅读)
  100. eSignSql += "\n"+filter;
  101. // 执行SQL查询并将结果封装为JSON对象(包含字段映射关系)
  102. JSONObject data = this.getData(eSignSql, context, entrys,eSignTemplateNum);
  103. System.out.println("=====data====="+data.toString());
  104. // 重新组装电子签模板数据为JSON对象
  105. JSONObject jsonObject = this.reassembleData(eSignFile, eSignTemplateNum ,context);
  106. System.out.println("=====jsonObject====="+jsonObject);
  107. // 合并查询数据与模板数据,返回合并后的JSON对象
  108. JSONObject newJSONObject = utils.mergeAgreements(data, jsonObject);
  109. System.out.println("=====newJSONObject====="+newJSONObject);
  110. return newJSONObject;
  111. }else {
  112. // 若数据源无效,直接获取电子签模板信息
  113. ESignTemplateInfo eSignFile = fieldMappingInfo.getESignFile();
  114. String eSignTemplateNum = eSignFile.getESignTemplateNum();
  115. // 重新组装模板数据并返回
  116. JSONObject jsonObject = this.reassembleData(eSignFile,eSignTemplateNum, context);
  117. return jsonObject;
  118. }
  119. }
  120. /**
  121. * 执行SQL查询并将结果封装为JSON对象
  122. * @param sql 要执行的查询SQL
  123. * @param context 上下文对象
  124. * @param entrys 字段映射明细集合
  125. * @return 封装后的JSON对象,包含电子签模板各字段信息
  126. */
  127. public JSONObject getData(String sql,Context context,FieldMappingEntryCollection entrys,String eSignTemplateNum){
  128. // 创建JSON对象用于存储最终封装的数据
  129. JSONObject jsonObject = new JSONObject();
  130. try {
  131. // 执行SQL查询,获取结果集
  132. IRowSet iRowSet1 = DBUtil.executeQuery(context, sql);
  133. // 遍历结果集中的每一行数据
  134. while (iRowSet1.next()){
  135. // 遍历每个字段映射明细项
  136. for (int i = 0; i <entrys.size(); i++) {
  137. // 获取当前索引对应的字段映射明细信息
  138. FieldMappingEntryInfo fieldMappingEntryInfo = entrys.get(i);
  139. // 获取明细项中关联的电子签模板字段信息
  140. ESignTemplateFileEntryFieldInfo eField = fieldMappingEntryInfo.getEField();
  141. // 判断该字段是否无效(已废弃)
  142. boolean invalid = eField.isInvalid();
  143. // 若字段无效,跳过当前循环(不处理)
  144. if (invalid){
  145. continue;
  146. }
  147. // 获取明细项中关联的电子签模板明细信息
  148. ESignTemplateFileEntryInfo template = fieldMappingEntryInfo.getTemplate();
  149. // 获取电子签模板的ID
  150. String eSignTemplateId = template.getESignTemplateId();
  151. // 从JSON对象中获取该模板ID对应的子JSON对象
  152. JSONObject templateJSON = jsonObject.getJSONObject(eSignTemplateId);
  153. // 若模板对应的子JSON对象不存在,则创建并初始化(设置ID和名称)
  154. if (templateJSON==null){
  155. templateJSON = new JSONObject();
  156. templateJSON.put("id",eSignTemplateId); // 设置模板ID
  157. templateJSON.put("name",template.getName()); // 设置模板名称
  158. templateJSON.put("eSignTemplateNum",eSignTemplateNum);
  159. jsonObject.put(eSignTemplateId,templateJSON); // 将模板信息存入主JSON对象
  160. }
  161. // 从模板子JSON对象中获取字段信息对应的子JSON对象
  162. JSONObject fields = templateJSON.getJSONObject("fields");
  163. // 若字段信息子JSON对象不存在,则创建并添加到模板子JSON中
  164. if (fields == null){
  165. fields = new JSONObject();
  166. templateJSON.put("fields",fields);
  167. }
  168. // 获取电子签模板字段的ID
  169. String templateFieldId = eField.getTemplateFieldId();
  170. // 创建用于存储字段值信息的JSON对象
  171. JSONObject value = new JSONObject();
  172. value.put("name",eField.getTemplateFieldName()); // 设置字段名称
  173. // 获取明细项中关联的数据源字段信息
  174. DataConfigSelectFieldEntryInfo dataSourceField = fieldMappingEntryInfo.getDataSourceField();
  175. if (dataSourceField==null){
  176. value.put("value","");
  177. value.put("dataFormat", eField.getDataFormat());
  178. }else {
  179. // 获取数据源字段的映射键(对应数据库列名)
  180. String name = dataSourceField.getMappingKey();
  181. // 去除映射键中的双引号(处理可能的格式问题)
  182. name = name.replace("\"","");
  183. // 从结果集中获取该字段对应的值,并存入字段值JSON对象
  184. value.put("value",iRowSet1.getObject(name));
  185. // 设置字段的数据类型(取自数据源字段的类型别名)
  186. value.put("dataType",dataSourceField.getDataType().getAlias());
  187. if (dataSourceField.getDataType().getAlias().equals("Date")){
  188. Object object = iRowSet1.getObject(name);
  189. if(object!=null){
  190. SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
  191. value.put("value",simpleDateFormat.format(iRowSet1.getDate(name)));
  192. }
  193. value.put("dataFormat", eField.getDataFormat());
  194. }else if(dataSourceField.getDataType().getAlias().equals("Enum")){
  195. String dataEntry = dataSourceField.getDataEntry();
  196. if (dataEntry!=null&&!dataEntry.equals("")){
  197. Object enumByValue = com.kingdee.shr.base.syssetting.app.util.MetaDataUtil
  198. .findEnumByValue(dataEntry, iRowSet1.getObject(name));
  199. if (enumByValue instanceof Enum){
  200. Enum e = (Enum) enumByValue;
  201. value.put("value", e.getAlias());
  202. }
  203. }
  204. }
  205. }
  206. if (eField.getComponentType().getValue()==6||eField.getComponentType().getValue()==106){
  207. value.put("positionX",eField.getPositionX());
  208. value.put("positionY",eField.getPositionY());
  209. value.put("pageNum",eField.getPageNum());
  210. }
  211. // 将字段值信息存入字段信息子JSON对象(以模板字段ID为键)
  212. fields.put(templateFieldId,value);
  213. }
  214. }
  215. } catch (BOSException e) {
  216. // BOS异常时,封装为运行时异常抛出
  217. throw new RuntimeException(e);
  218. } catch (SQLException e) {
  219. // SQL异常时,封装为运行时异常抛出
  220. throw new RuntimeException(e);
  221. }
  222. // 返回封装好的JSON对象
  223. return jsonObject;
  224. }
  225. /**
  226. * 构建查询字段映射信息的实体视图
  227. * @param number 字段映射的编号,用于过滤
  228. * @return 构建好的实体视图信息
  229. * @throws ParserException 解析异常
  230. */
  231. public EntityViewInfo getEntityViewInfo(String number) throws ParserException {
  232. // 创建实体视图信息对象
  233. EntityViewInfo entityViewInfo = new EntityViewInfo();
  234. // 创建选择项集合,用于指定查询返回的字段
  235. SelectorItemCollection selectorItemCollection = new SelectorItemCollection();
  236. selectorItemCollection.add("*"); // 选择所有基础字段
  237. selectorItemCollection.add("eSignFile.*"); // 选择关联的电子签文件的所有字段
  238. selectorItemCollection.add("dataSource.*"); // 选择关联的数据源的所有字段
  239. selectorItemCollection.add("entrys.*"); // 选择关联的明细项的所有字段
  240. selectorItemCollection.add("entrys.eField.*"); // 选择明细项中电子签字段的所有字段
  241. selectorItemCollection.add("entrys.dataSourceField.*"); // 选择明细项中数据源字段的所有字段
  242. selectorItemCollection.add("entrys.template.*"); // 选择明细项中模板的所有字段
  243. // 为实体视图设置选择项(指定查询返回的字段集)
  244. entityViewInfo.setSelector(selectorItemCollection);
  245. // 创建过滤信息对象,用于设置查询条件
  246. FilterInfo filterInfo = new FilterInfo();
  247. // 添加过滤条件:字段映射的编号等于传入的number
  248. filterInfo.getFilterItems().add(new FilterItemInfo("number",number));
  249. // 为实体视图设置过滤条件
  250. entityViewInfo.setFilter(filterInfo);
  251. // 返回构建好的实体视图信息
  252. return entityViewInfo;
  253. }
  254. /**
  255. * 重新组装数据(当前未实现完整逻辑,仅基础框架)
  256. * @param eSignFile 电子签模板信息
  257. * @param context 上下文对象
  258. * @return 重新组装后的JSON对象(数据可能为null)
  259. */
  260. public JSONObject reassembleData(ESignTemplateInfo eSignFile,String eSignTemplateNum,Context context){
  261. // 获取电子签模板的ID
  262. BOSUuid id = eSignFile.getId();
  263. // 声明用于存储组装后数据的JSON对象
  264. JSONObject dataJSON ;
  265. try {
  266. // 初始化数据JSON对象
  267. dataJSON = new JSONObject();
  268. // 创建实体视图信息对象
  269. EntityViewInfo entityViewInfo = new EntityViewInfo();
  270. // 创建选择项集合,指定查询返回的字段
  271. SelectorItemCollection selectorItemCollection = new SelectorItemCollection();
  272. selectorItemCollection.add("*"); // 选择所有基础字段
  273. selectorItemCollection.add("Parent1.*"); // 选择父级对象的所有字段
  274. // 为实体视图设置选择项
  275. entityViewInfo.setSelector(selectorItemCollection);
  276. // 创建过滤信息对象
  277. FilterInfo filterInfo = new FilterInfo();
  278. // 添加过滤条件:字段未失效(Invalid为false)
  279. filterInfo.getFilterItems().add(new FilterItemInfo("Invalid",1, CompareType.NOTEQUALS));
  280. // 添加过滤条件:父级的父级ID等于电子签模板ID
  281. filterInfo.getFilterItems().add(new FilterItemInfo("Parent1.Parent.id",id));
  282. // 为实体视图设置过滤条件
  283. entityViewInfo.setFilter(filterInfo);
  284. // 根据实体视图查询电子签模板字段明细集合
  285. ESignTemplateFileEntryFieldCollection eFields = ESignTemplateFileEntryFieldFactory.
  286. getLocalInstance(context).getESignTemplateFileEntryFieldCollection(entityViewInfo);
  287. // 遍历字段明细集合
  288. for (int i = 0; i < eFields.size(); i++) {
  289. // 获取当前索引对应的电子签模板字段明细
  290. ESignTemplateFileEntryFieldInfo eFile = eFields.get(i);
  291. // 获取该字段明细的父级对象(模板明细)
  292. ESignTemplateFileEntryInfo parent1 = eFile.getParent1();
  293. // 获取电子签模板ID
  294. String eSignTemplateId = parent1.getESignTemplateId();
  295. // 获取电子签模板名称
  296. String name = parent1.getName();
  297. // 从数据JSON中获取模板ID对应的子JSON对象
  298. JSONObject signTemplate = dataJSON.getJSONObject(eSignTemplateId);
  299. // 若模板子JSON对象不存在,则创建并初始化
  300. if (signTemplate == null){
  301. signTemplate = new JSONObject();
  302. signTemplate.put("name",name); // 设置模板名称
  303. signTemplate.put("id",eSignTemplateId); // 设置模板ID
  304. signTemplate.put("eSignTemplateNum",eSignTemplateNum);
  305. JSONObject fields = new JSONObject(); // 创建字段信息JSON对象
  306. signTemplate.put("fields",fields); // 将字段信息存入模板JSON
  307. dataJSON.put(eSignTemplateId,signTemplate);
  308. }
  309. // 从模板子JSON中获取字段信息JSON对象
  310. JSONObject fields = signTemplate.getJSONObject("fields");
  311. // 获取模板字段ID
  312. String templateFieldId = eFile.getTemplateFieldId();
  313. // 从字段信息JSON中获取该字段ID对应的子JSON对象
  314. JSONObject field = fields.getJSONObject(templateFieldId);
  315. // 若字段子JSON对象不存在,则创建并添加到字段信息JSON
  316. if (field==null){
  317. field = new JSONObject();
  318. fields.put(templateFieldId,field);
  319. }
  320. // 获取模板字段名称
  321. String templateFieldName = eFile.getTemplateFieldName();
  322. // 设置字段名称到字段子JSON
  323. field.put("name",templateFieldName);
  324. // 获取字段组件类型
  325. ComponentTypeEnum componentType = eFile.getComponentType();
  326. // 设置字段数据类型(取自组件类型的别名)
  327. field.put("dataType",componentType.getAlias());
  328. field.put("dataFormat",eFile.getDataFormat());
  329. field.put("isRequired",eFile.isRequired());
  330. field.put("seq",eFile.getSeq());
  331. // 字段值暂设为null
  332. field.put("value",null);
  333. }
  334. } catch (BOSException e) {
  335. // BOS异常时,封装为运行时异常抛出
  336. throw new RuntimeException(e);
  337. }
  338. // 返回重新组装后的JSON对象
  339. return dataJSON;
  340. }
  341. }