package com.kingdee.eas.custom.esign.utils; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.JSONObject; import com.kingdee.bos.BOSException; import com.kingdee.bos.metadata.entity.EntityViewInfo; import com.kingdee.bos.metadata.entity.FilterInfo; import com.kingdee.bos.metadata.entity.FilterItemInfo; import com.kingdee.eas.custom.entryconfig.DataConfigSelectFieldEntryCollection; import com.kingdee.eas.custom.entryconfig.DataConfigSelectFieldEntryInfo; import com.kingdee.bos.Context; import com.kingdee.eas.custom.esign.*; import com.kingdee.shr.base.syssetting.MSFServiceFacadeFactory; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; /** * 电子签名字段映射工具类 * 提供电子签名相关的字段处理、SQL获取、模板信息获取、JSON合并等工具方法 */ public class ESignFieldMappingUtils { // /** // * 生成电子签名SQL字段字符串(已注释,备用逻辑) // * @param fields 字段映射集合 // * @return 拼接后的SQL字段字符串(格式:数据库字段 as 映射键, ...) // */ // public String getESignSqlField(FieldMappingEntryCollection fields){ // String sqlField = ""; // // 遍历字段映射集合 // for (int i = 0; i < fields.size(); i++) { // // 获取当前字段映射信息 // FieldMappingEntryInfo field = fields.get(i); // // 获取数据源字段信息 // DataConfigSelectFieldEntryInfo dataSourceField = field.getDataSourceField(); // // 获取映射键 // String mappingKey = dataSourceField.getMappingKey(); // // 获取数据库字段名 // String databaseName = dataSourceField.getDatabaseName(); // // 拼接SQL字段字符串(数据库字段 as 映射键) // sqlField+=databaseName+" as "+mappingKey; // // 判断是否为最后一个字段,最后一个字段后加换行,否则加逗号 // if (i==fields.size()-1){ // sqlField+="\n"; // }else { // sqlField+=","; // } // } // // 返回拼接好的SQL字段字符串 // return sqlField; // } /** * 从字段映射集合中提取数据源字段集合 * @param fields 字段映射集合(包含字段映射关系) * @return 数据源字段集合(仅包含数据源字段信息) */ public DataConfigSelectFieldEntryCollection getESignSqlField(FieldMappingEntryCollection fields){ // 初始化数据源字段集合 DataConfigSelectFieldEntryCollection dataConfigSelectFieldEntryCollection = new DataConfigSelectFieldEntryCollection(); // 遍历字段映射集合 for (int i = 0; i < fields.size(); i++) { // 获取当前字段映射信息 FieldMappingEntryInfo field = fields.get(i); // 从字段映射中提取数据源字段 DataConfigSelectFieldEntryInfo dataSourceField = field.getDataSourceField(); // 将数据源字段添加到结果集合中 if (dataSourceField!=null){ dataConfigSelectFieldEntryCollection.add(dataSourceField); } } // 返回提取后的数据源字段集合 return dataConfigSelectFieldEntryCollection; } /** * 根据数据配置编号获取电子签名相关SQL * @param dataConfigNumber 数据配置编号(用于标识特定的数据配置) * @param context 上下文对象(金蝶BOS框架上下文,包含环境信息) * @return 获取到的SQL字符串 */ public String getESignSql(String dataConfigNumber,Context context){ // 初始化服务调用参数映射 Map getSqlServiceMap = new HashMap(); // 设置参数:数据配置编号 getSqlServiceMap.put("number",dataConfigNumber); // 声明SQL结果变量 Object sql = null; try { // 调用本地服务获取SQL,服务名为"getSqlService",传入参数映射 sql = MSFServiceFacadeFactory.getLocalInstance(context).processService("getSqlService", getSqlServiceMap); } catch (Exception e) { // 捕获异常并包装为运行时异常抛出 throw new RuntimeException(e); } // 将SQL结果转为字符串返回 return sql.toString(); } /** * 根据ID获取电子签名模板信息 * @param id 模板ID(用于唯一标识模板) * @param context 上下文对象(金蝶BOS框架上下文) * @return 电子签名模板信息(当前逻辑未实现,返回null) * @throws BOSException 金蝶BOS框架异常 */ public ESignTemplateInfo getTemplateInfo(String id,Context context) throws BOSException { // 创建实体视图信息(用于查询时指定视图条件) EntityViewInfo entityViewInfo = new EntityViewInfo(); // 创建过滤信息对象(用于设置查询过滤条件) FilterInfo filterInfo = new FilterInfo(); // 向过滤信息中添加过滤项:根据ID过滤(字段名为"id",值为传入的id) filterInfo.getFilterItems().add(new FilterItemInfo("id",id)); // 将过滤信息设置到实体视图中 entityViewInfo.setFilter(filterInfo); // 调用电子签名模板工厂获取符合条件的模板集合(当前未使用返回的集合) ESignTemplateFactory.getLocalInstance(context).getESignTemplateCollection(entityViewInfo); // 方法暂未实现,返回null return null; } /** * 合并两个协议JSONObject对象的方法 * @param baseJson 基础JSON对象(被合并的原始数据,优先级较低) * @param newJson 新JSON对象(待合并的数据,优先级较高,用于覆盖/补充原始数据) * @return 合并后的JSONObject * @throws IllegalArgumentException 当基础JSON为null时抛出 */ public JSONObject mergeAgreements(JSONObject baseJson, JSONObject newJson) { // 基础JSON非空校验 if (baseJson == null) { throw new IllegalArgumentException("基础JSON数据不能为null"); } // 若新JSON为null,直接返回基础JSON if (newJson == null) { return baseJson; } // 遍历新JSON中的所有协议Key for (String agreementKey : newJson.keySet()) { try { // 从新JSON中获取当前Key对应的协议对象 JSONObject newAgreement = newJson.getJSONObject(agreementKey); // 若当前协议不是JSONObject类型,跳过处理 if (newAgreement == null) { continue; } // 若基础JSON中已包含当前协议Key if (baseJson.containsKey(agreementKey)) { // 从基础JSON中获取对应协议对象 JSONObject baseAgreement = baseJson.getJSONObject(agreementKey); // 合并两个协议对象的内部字段 mergeSingleAgreement(baseAgreement, newAgreement); } else { // 若基础JSON中不包含当前协议Key,直接添加新协议到基础JSON baseJson.put(agreementKey, newAgreement); } } catch (JSONException e) { // 捕获JSON解析异常,打印错误信息后继续处理其他协议 System.err.println("处理协议[" + agreementKey + "]时出错:" + e.getMessage()); continue; } } // 返回合并后的基础JSON return baseJson; } // /** // * 合并两个单个协议对象的内部字段 // * @param baseAgreement 基础协议对象(被合并的原始协议) // * @param newAgreement 新协议对象(待合并的协议,用于覆盖/补充原始协议) // */ // private void mergeSingleAgreement(JSONObject baseAgreement, JSONObject newAgreement) { // // 合并协议的基础属性:name(若新协议有name则覆盖) // if (newAgreement.getString("name") != null) { // baseAgreement.put("name", newAgreement.getString("name")); // } // // 合并协议的基础属性:id(若新协议有id则覆盖) // if (newAgreement.getString("id") != null) { // baseAgreement.put("id", newAgreement.getString("id")); // } // // 合并协议的基础属性:dataType(dataType则覆盖) // if (newAgreement.getString("dataType") != null) { // baseAgreement.put("dataType", newAgreement.getString("dataType")); // } // // 合并协议的基础属性:dataFormat(dataFormat则覆盖) // if (newAgreement.getString("dataFormat") != null) { // baseAgreement.put("dataFormat", newAgreement.getString("dataFormat")); // } // // // 从新协议中获取fields字段(字段集合) // JSONObject newFields = newAgreement.getJSONObject("fields"); // // 若新协议的fields为空或不存在,无需合并字段,直接返回 // if (newFields == null || newFields.isEmpty()) { // return; // } // // // 从基础协议中获取fields字段(字段集合) // JSONObject baseFields = baseAgreement.getJSONObject("fields"); // // 若基础协议中没有fields字段,直接将新协议的fields设置到基础协议 // if (baseFields == null) { // baseAgreement.put("fields", newFields); // return; // } // // // 遍历新协议fields中的所有字段Key // for (String fieldKey : newFields.keySet()) { // // 从新协议fields中获取当前字段对象 // JSONObject newField = newFields.getJSONObject(fieldKey); // if (newField != null) { // // 获取新字段的value值 // Object value = newField.get("value"); // // 若新字段value为null且基础fields中已存在该字段,则跳过(不覆盖现有有效数据) // if (value == null && baseFields.containsKey(fieldKey)) { // JSONObject jsonObject1 = baseFields.getJSONObject(fieldKey); // String dataType = jsonObject1.getString("dataType"); // String dataFormat = jsonObject1.getString("dataFormat"); // newField.put("dataType",dataType); // newField.put("dataFormat",dataFormat); // //continue; // } //// else { //// String dataType = baseFields.getString("dataType"); //// String dataFormat = baseFields.getString("dataFormat");0 //// newField.put("dataType",dataType); //// newField.put("dataFormat",dataFormat); //// } // // 将新字段添加/覆盖到基础fields中 // baseFields.put(fieldKey, newField); // } // } // } /** * 合并单个协议对象内部的字段 * @param baseAgreement 基础协议对象(被合并的原始协议) * @param newAgreement 新协议对象(要合并的协议,用于覆盖/补充原始协议) */ private void mergeSingleAgreement(JSONObject baseAgreement, JSONObject newAgreement) { // 协议级字段:优先使用newAgreement的name、id、dataType、dataFormat if (newAgreement.getString("name") != null) { baseAgreement.put("name", newAgreement.getString("name")); } if (newAgreement.getString("id") != null) { baseAgreement.put("id", newAgreement.getString("id")); } if (newAgreement.getString("dataType") != null) { baseAgreement.put("dataType", newAgreement.getString("dataType")); } if (newAgreement.getString("dataFormat") != null) { baseAgreement.put("dataFormat", newAgreement.getString("dataFormat")); } // 从新协议中获取fields JSONObject newFields = newAgreement.getJSONObject("fields"); if (newFields == null || newFields.isEmpty()) { return; // 新协议无fields,无需处理 } // 从基础协议中获取fields(若不存在则直接使用新协议的fields) JSONObject baseFields = baseAgreement.getJSONObject("fields"); if (baseFields == null) { baseAgreement.put("fields", newFields); // base无fields,直接用new的fields return; } // 基础协议存在fields,遍历新协议的fields进行合并 for (String fieldKey : newFields.keySet()) { JSONObject newField = newFields.getJSONObject(fieldKey); if (newField == null) { continue; } // 若基础协议的fields中没有当前字段,直接添加新字段(以new为主) if (!baseFields.containsKey(fieldKey)) { baseFields.put(fieldKey, newField); continue; } // 基础协议存在当前字段,进行字段级合并 JSONObject baseField = baseFields.getJSONObject(fieldKey); // 1. new的dataType和dataFormat优先覆盖base String newDataType = newField.getString("dataType"); if (newDataType != null) { baseField.put("dataType", newDataType); } String newDataFormat = newField.getString("dataFormat"); if (newDataFormat != null) { baseField.put("dataFormat", newDataFormat); } // 2. 其他字段(如name、value等):以base为主,new有非空值时覆盖 for (String key : newField.keySet()) { if ("dataType".equals(key) || "dataFormat".equals(key)) { continue; // 已处理过的字段跳过 } Object newValue = newField.get(key); if (newValue != null) { baseField.put(key, newValue); // 仅new有值时覆盖base } } // 将合并后的字段放回baseFields baseFields.put(fieldKey, baseField); } } // ---------- 以下为重载方法,支持JSON字符串的合并 ---------- /** * 合并两个JSON字符串(重载方法) * @param baseJsonStr 基础JSON字符串 * @param newJsonStr 新JSON字符串 * @return 合并后的JSONObject * @throws IllegalArgumentException 当JSON字符串解析失败时抛出 */ public JSONObject mergeAgreements(String baseJsonStr, String newJsonStr) { try { // 将基础JSON字符串解析为JSONObject JSONObject baseJson = JSONObject.parseObject(baseJsonStr); // 将新JSON字符串解析为JSONObject JSONObject newJson = JSONObject.parseObject(newJsonStr); // 调用JSON对象合并方法 return mergeAgreements(baseJson, newJson); } catch (JSONException e) { // 解析失败时抛出异常,包含错误信息 throw new IllegalArgumentException("JSON字符串解析失败:" + e.getMessage(), e); } } // ---------- 以下为重载方法,支持从文件读取JSON并合并 ---------- /** * 从文件读取JSON字符串并合并(重载方法) * @param baseFilePath 基础JSON文件路径 * @param newFilePath 新JSON文件路径 * @return 合并后的JSONObject * @throws IOException 当文件读取失败时抛出 */ public JSONObject mergeAgreementsFromFile(String baseFilePath, String newFilePath) throws IOException { // 读取基础JSON文件内容为字符串 String baseJsonStr = readFileToString(baseFilePath); // 读取新JSON文件内容为字符串 String newJsonStr = readFileToString(newFilePath); // 调用JSON字符串合并方法 return mergeAgreements(baseJsonStr, newJsonStr); } /** * 将文件内容读取为字符串(使用UTF-8编码) * @param filePath 文件路径 * @return 文件内容字符串 * @throws IOException 当文件不存在或读取失败时抛出 */ private String readFileToString(String filePath) throws IOException { // 根据文件路径创建File对象 File file = new File(filePath); // 使用try-with-resources自动关闭流:创建文件输入流和Scanner try (FileInputStream fis = new FileInputStream(file); java.util.Scanner scanner = new java.util.Scanner(fis, StandardCharsets.UTF_8.name())) { // 设置Scanner的分隔符为文件开始(即读取整个文件) scanner.useDelimiter("\\A"); // 若有内容则返回内容,否则返回空字符串 return scanner.hasNext() ? scanner.next() : ""; } } // ---------- 测试方法入口 ---------- /** * 主方法:测试入口 * @param args 命令行参数 */ public static void main(String[] args) { // 测试场景1:基础合并 + 新增数据(被注释,可取消注释执行) // testBasicMerge(); // // // 测试场景2:新JSON为null(被注释,可取消注释执行) // testNewJsonNull(); // 测试场景3:字段value为null的处理(被注释,可取消注释执行) //testNullValueField(); } /** * 测试场景1:基础合并逻辑 * 验证已有协议字段覆盖、新增协议及字段的合并效果 */ // private static void testBasicMerge() { // System.out.println("===== 测试场景1:基础合并 ====="); // // 基础JSON字符串(原始数据) // String baseJsonStr = " {\n" + // " \"借款协议_id\": {\n" + // " \"name\": \"借款协议\",\n" + // " \"id\": \"借款协议_id\",\n" + // " \"fields\": {\n" + // " \"借款协议_Field_id\": {\"dataType\": \"String\", \"name\": \"借款协议Field1\", \"value\": \"001\"},\n" + // " \"借款协议_Field_id1\": {\"dataType\": \"String\", \"name\": \"借款协议Field2\", \"value\": null}\n" + // " }\n" + // " },\n" + // " \"投资合同_id\": {\n" + // " \"name\": \"投资合同\",\n" + // " \"id\": \"投资合同_id\",\n" + // " \"fields\": {\"投资合同_Field_id1\": {\"dataType\": \"String\", \"name\": \"投资合同Field2\", \"value\": \"小明\"}}\n" + // " }\n" + // " }"; // // // 新JSON字符串(待合并数据) // String newJsonStr = "{\n" + // " \"借款协议_id\": {\n" + // " \"name\": \"借款协议(修改)\",\n" + // " \"id\": \"借款协议_id\",\n" + // " \"fields\": {\n" + // " \"借款协议_Field_id1\": {\"dataType\": \"String\", \"name\": \"借款协议Field2\", \"value\": \"002\"},\n" + // " \"借款协议_Field_id2\": {\"dataType\": \"String\", \"name\": \"借款协议Field3\", \"value\": \"新字段\"}\n" + // " }\n" + // " },\n" + // " \"业务协议_id\": {\n" + // " \"name\": \"业务协议\",\n" + // " \"id\": \"业务协议_id\",\n" + // " \"fields\": {\"业务协议_Field_id\": {\"dataType\": \"String\", \"name\": \"业务协议Field1\", \"value\": \"19892761659\"}}\n" + // " }\n" + // " }"; // // try { // // 执行合并 // JSONObject mergedJson = mergeAgreements(baseJsonStr, newJsonStr); // // 打印合并结果(格式化输出) // System.out.println("合并结果\n" + JSONObject.toJSONString(mergedJson, true)); // } catch (Exception e) { // // 捕获并打印合并失败信息 // System.err.println("合并失败:" + e.getMessage()); // } // System.out.println("------------------------\n"); // } // // /** // * 测试场景2:新JSON为null的情况 // * 验证当新数据为null时,是否返回基础数据 // */ // private static void testNewJsonNull() { // System.out.println("===== 测试场景2:新JSON为null ====="); // // 基础JSON字符串 // String baseJsonStr = "{\"投资合同_id\": {\"name\": \"投资合同\", \"id\": \"投资合同_id\"}}"; // try { // // 传入新JSON为null,执行合并 // JSONObject mergedJson = mergeAgreements(baseJsonStr, null); // // 打印合并结果 // System.out.println("合并结果\n" + JSONObject.toJSONString(mergedJson, true)); // } catch (Exception e) { // // 捕获并打印合并失败信息 // System.err.println("合并失败:" + e.getMessage()); // } // System.out.println("------------------------\n"); // } /** * 测试场景3:字段value为null的处理 * 验证当新字段value为null时,是否保留基础字段的有效数据 */ // private static void testNullValueField() { // System.out.println("===== 测试场景3:字段value为null ====="); // // 基础JSON字符串(包含有效value的字段) // String baseJsonStr = """ // { // "借款协议_id": { // "fields": {"借款协议_Field_id": {"value": "有效数据"}} // } // }"""; // // // 新JSON字符串(包含value为null的字段和新增字段) // String newJsonStr = """ // { // "借款协议_id": { // "fields": {"借款协议_Field_id": {"value": null}, "新字段": {"value": "新数据"}} // } // }"""; // // try { // // 执行合并 // JSONObject mergedJson = mergeAgreements(baseJsonStr, newJsonStr); // // 打印合并结果(验证value为null的字段是否被忽略) // System.out.println("合并结果(验证字段value为null时的处理):\n" + JSONObject.toJSONString(mergedJson, true)); // } catch (Exception e) { // // 捕获并打印合并失败信息 // System.err.println("合并失败:" + e.getMessage()); // } // } }