LiuYing 1 dienu atpakaļ
vecāks
revīzija
52cf671eef

+ 23 - 3
src/com/kingdee/eas/hr/org/app/OrgUnitOptFacadeControllerBeanEx.java

@@ -3,6 +3,9 @@ package com.kingdee.eas.hr.org.app;
 import com.alibaba.fastjson.JSONObject;
 import com.kingdee.bos.BOSException;
 import com.kingdee.bos.Context;
+import com.kingdee.eas.basedata.org.AdminOrgUnitCollection;
+import com.kingdee.eas.basedata.org.AdminOrgUnitFactory;
+import com.kingdee.eas.basedata.org.IAdminOrgUnit;
 import com.kingdee.eas.common.EASBizException;
 import com.kingdee.eas.custom.beisen.synchronousorg.synchronousOrg;
 import com.kingdee.eas.custom.beisen.synchronousorg.synchronousOrgControllerBean;
@@ -34,6 +37,21 @@ public class OrgUnitOptFacadeControllerBeanEx extends OrgUnitOptFacadeController
         } catch (BOSException e) {
             System.out.println("同步组织失败"+e.getMessage());
         }
+        // 获取组织信息本地实例
+        IAdminOrgUnit localInstance = null;
+        try {
+            localInstance = AdminOrgUnitFactory.getLocalInstance(context);
+        } catch (BOSException e) {
+            throw new RuntimeException(e);
+        }
+        String number = "";
+        // 根据查询条件获取组织信息集合
+        try {
+            AdminOrgUnitCollection adminOrgUnitCollection = localInstance.getAdminOrgUnitCollection("where id = '"+id+"'");
+            number = adminOrgUnitCollection.get(0).getNumber();
+        } catch (BOSException e) {
+            throw new RuntimeException(e);
+        }
         // 创建 BeiSenUtils 工具类的实例,用于处理与外部接口交互的相关操作
         BeiSenUtils beiSenUtils = new BeiSenUtils(context);
         // 从工具类中获取配置文件的 Properties 对象
@@ -42,7 +60,8 @@ public class OrgUnitOptFacadeControllerBeanEx extends OrgUnitOptFacadeController
         String url = propt.getProperty(urlKey);
         try {
             // 将组织单元 ID 进行 UTF-8 编码,并拼接到 URL 后面作为参数
-            url = url + "?originalId=" + URLEncoder.encode(id, "UTF-8");
+            url = url + "?originalId=" + URLEncoder.encode(number, "UTF-8");
+            System.out.println(url);
         } catch (UnsupportedEncodingException e) {
             // 如果编码过程中出现不支持的编码异常,将其包装成运行时异常抛出
             System.out.println(e.getMessage());
@@ -97,12 +116,13 @@ public class OrgUnitOptFacadeControllerBeanEx extends OrgUnitOptFacadeController
      */
     @Override
     protected void _sealUpOrg(Context ctx, String unitID) throws BOSException, EASBizException {
+        // 调用父类的封存组织单元方法
+        super._sealUpOrg(ctx, unitID);
         // 打印日志,标记当前执行的方法
         System.out.println("===============com.kingdee.eas.hr.org.app.OrgUnitOptFacadeControllerBeanEx._sealUpOrg============");
         // 调用同步操作方法,将组织单元标记为禁用
         syncOrgOperation(ctx,"DEPARTMENTS_DISABLE", unitID);
-        // 调用父类的封存组织单元方法
-        super._sealUpOrg(ctx, unitID);
+
     }
 
     /**

+ 3 - 0
websrc/com/kingdee/eas/custom/esign/service/GetESignConfigDataService.java

@@ -105,10 +105,13 @@ public class GetESignConfigDataService implements IHRMsfService {
             eSignSql += "\n"+filter;
             // 执行SQL查询并将结果封装为JSON对象(包含字段映射关系)
             JSONObject data = this.getData(eSignSql, context, entrys,eSignTemplateNum);
+            System.out.println("=====data====="+data.toString());
             // 重新组装电子签模板数据为JSON对象
             JSONObject jsonObject = this.reassembleData(eSignFile, eSignTemplateNum ,context);
+            System.out.println("=====jsonObject====="+jsonObject);
             // 合并查询数据与模板数据,返回合并后的JSON对象
             JSONObject newJSONObject = utils.mergeAgreements(data, jsonObject);
+            System.out.println("=====newJSONObject====="+newJSONObject);
             return newJSONObject;
 
         }else {

+ 166 - 75
websrc/com/kingdee/eas/custom/esign/service/OnboardingSalaryDataService.java

@@ -11,82 +11,173 @@ import com.kingdee.bos.util.BOSUuid;
  * 202602
  */
 public class OnboardingSalaryDataService extends OtherESignConfigDataService {
-
-
 	public String getSql(String id) {
-		StringBuilder sql = new StringBuilder();
-
-		// -------------------------- SELECT子句 --------------------------
-		// 基础字段:人员姓名、身份证号、甲方名称、入职日期
-		// 薪资计算字段:固定工资、试用期固定工资、绩效奖金、各类补贴(均为税前)
-		sql.append("SELECT \n");
-		sql.append("    person.FNAME_L2 AS person_name ,\n");
-		sql.append("    person.FIDCardNO AS idcard ,\n");
-		sql.append("    firstParty.FName_l2 as firstPartyName ,\n");
-		sql.append("    elation.FEnterDate AS eDate ,\n");
-		// 1. 固定工资(税前)= 标准基本工资+综合工资+其他工资+加班工资
-		sql.append("    ISNULL(SUM(CASE WHEN sitem.FNUMBER IN ('TD01', 'T012', 'T013', 'TD02') THEN fas.FMoney ELSE 0 END), 0) AS fixed_salary ,\n");
-		// 2. 试用期固定工资(税前)= 标准基本工资+综合工资+其他工资+加班工资
-		sql.append("    ISNULL(SUM(CASE WHEN sitem.FNUMBER IN ('TD01', 'T012', 'T013', 'TD02') THEN fas.FMoney ELSE 0 END), 0) AS prob_fixed_salary ,\n");
-		// 3. 绩效奖金(税前)= 标准绩效奖金
-		sql.append("    ISNULL(MAX(CASE WHEN sitem.FNUMBER = 'TD04' THEN fas.FMoney ELSE 0 END), 0) AS perf_bonus ,\n");
-		// 4. 试用期绩效奖金(税前)= 试用期标准绩效奖金
-		sql.append("    ISNULL(MAX(CASE WHEN sitem.FNUMBER = 'TD74' THEN fas.FMoney ELSE 0 END), 0) AS prob_perf_bonus ,\n");
-		// 5. 国内餐补 = 餐补补贴
-		sql.append("    ISNULL(MAX(CASE WHEN sitem.FNUMBER = 'T014' THEN fas.FMoney ELSE 0 END), 0) AS domestic_meal_subsidy ,\n");
-		// 6. 艰苦补贴 = 艰苦补贴
-		sql.append("    ISNULL(MAX(CASE WHEN sitem.FNUMBER = 'TD05' THEN fas.FMoney ELSE 0 END), 0) AS hardship_subsidy ,\n");
-		// 7. 社保公积金补贴 = 社保公积金补贴
-		sql.append("    ISNULL(MAX(CASE WHEN sitem.FNUMBER = 'TD101' THEN fas.FMoney ELSE 0 END), 0) AS social_fund , \n");
-
-		// 8. 总部人员产假工资:
-		sql.append("    ISNULL(SUM(CASE WHEN sitem.FNUMBER IN ('TD01', 'T012', 'TD101' ) THEN fas.FMoney ELSE 0 END), 0) AS hqMaternity   ,\n");
-		// 9. 月薪产假工资
-		sql.append("    ISNULL(SUM(CASE WHEN sitem.FNUMBER IN ('TD01', 'TD03', 'TD02', 'TD06' , 'TD101') THEN fas.FMoney ELSE 0 END), 0) AS msMaternity ,\n");
-		// 10.日薪产假工资
-		sql.append("    ISNULL(SUM(CASE WHEN sitem.FNUMBER IN ('TD01', 'TD06', 'TD07' ) THEN fas.FMoney ELSE 0 END), 0) AS dwMaternity  \n");
-
-		// -------------------------- FROM子句 --------------------------
-		// 表关联逻辑:
-		// 1. T_bd_Person(人员表)关联T_HR_EmpLaborRelation(用工关系表):取入职日期
-		// 2. 人员表关联T_HR_SFixAdjustSalary(固定薪资调整表):取薪资金额
-		// 3. 薪资表关联T_HR_SCmpItem(薪资项目表):按薪资项目编码过滤
-		// 4. 人员表关联T_HR_EmployeeContract(员工合同表):关联甲方信息
-		// 5. 合同表关联T_HR_LabContractFirstParty(合同甲方表):取甲方名称
-		sql.append("FROM \n");
-		sql.append("    T_bd_Person person \n");
-		sql.append("LEFT JOIN T_HR_EmpLaborRelation elation on person.fid = elation.FPersonID \n");
-		sql.append("LEFT JOIN T_HR_SFixAdjustSalary fas ON person.FID = fas.FPersonID\n");
-		sql.append("LEFT JOIN T_HR_SCmpItem sitem ON fas.FCmpItemID = sitem.FID\n");
-		sql.append("LEFT JOIN T_HR_EmployeeContract econtract on econtract.FEmployeeID = person.FID\n");
-		sql.append("LEFT JOIN T_HR_LabContractFirstParty firstParty on econtract.FContFirstPartyID = firstParty.FID \n");
-
-
-		sql.append("WHERE \n");
-		sql.append("    sitem.FNUMBER IN ('TD01', 'T012', 'T013', 'TD02', 'TD04', 'TD74', 'T014', 'TD05', 'TD101' ,'TD03' ,'TD06' ,'TD07') \n");
-		sql.append("    and fas.FLeffectDay = '2199-12-31 00:00:00' \n");
-		sql.append("    AND  econtract. FState = '1' AND  econtract.FNewState  = '1' AND  econtract.FIsNewestContract = '1'   \n");
-		BOSUuid read = BOSUuid.read(id);
-		BOSObjectType type = read.getType();
-		if (type.toString().equals("7BD37592")){//id类型为合同
-			sql.append("and  person.fid  in (select FEmployeeID from T_HR_EmployeeContract where fid = '"+id+"')" ) ;
-		}else  if (type.toString().equals("80EF7DED")){//id类型为员工felse
-			sql.append("and person.fid = '"+id+"'");
-		}
-		sql.append("GROUP BY \n");
-		sql.append("    person.FID, person.FNAME_L2 , elation.FEnterDate , person.FIDCardNO , firstParty.FName_l2 \n");
-
-		// -------------------------- ORDER BY子句 --------------------------
-		// 排序规则:按人员姓名升序排列
-		sql.append("ORDER BY \n");
-		sql.append("    person.FNAME_L2");
-
-		System.out.print("osfsql"+sql.toString());
-		return sql.toString();
-	}
-
-
-
+    	StringBuilder sql = new StringBuilder();
+    	
+    	// -------------------------- SELECT子句 --------------------------
+    	// 基础字段:人员姓名、身份证号、甲方名称、入职日期
+    	// 薪资计算字段:固定工资、试用期固定工资、绩效奖金、各类补贴(均为税前)
+    	sql.append("SELECT \n");
+    	sql.append("    person.FNAME_L2 AS person_name ,\n");
+    	sql.append("    person.FIDCardNO AS idcard ,\n");
+    	sql.append("    firstParty.FName_l2 as firstPartyName ,\n");
+    	sql.append("    elation.FEnterDate AS eDate ,\n");
+    	// 1. 固定工资(税前)= 标准基本工资+综合工资+其他工资+加班工资
+    	sql.append("    ISNULL(SUM(CASE WHEN sitem.FNUMBER IN ('TD01', 'T012', 'T013', 'TD02') THEN fas.FMoney ELSE 0 END), 0) AS fixed_salary ,\n");
+    	// 2. 试用期固定工资(税前)= 标准基本工资+综合工资+其他工资+加班工资
+    	sql.append("    ISNULL(SUM(CASE WHEN sitem.FNUMBER IN ('TD01', 'T012', 'T013', 'TD02') THEN fas.FMoney ELSE 0 END), 0) AS prob_fixed_salary ,\n");
+    	// 3. 绩效奖金(税前)= 标准绩效奖金
+    	sql.append("    ISNULL(SUM(CASE WHEN sitem.FNUMBER = 'TD04' THEN fas.FMoney ELSE 0 END), 0) AS perf_bonus ,\n");
+    	// 4. 试用期绩效奖金(税前)= 试用期标准绩效奖金
+    	sql.append("    ISNULL(SUM(CASE WHEN sitem.FNUMBER = 'TD74' THEN fas.FMoney ELSE 0 END), 0) AS prob_perf_bonus ,\n");
+    	// 5. 国内餐补 = 餐补补贴
+    	sql.append("    ISNULL(SUM(CASE WHEN sitem.FNUMBER = 'T014' THEN fas.FMoney ELSE 0 END), 0) AS domestic_meal_subsidy ,\n");
+    	// 6. 艰苦补贴 = 艰苦补贴
+    	sql.append("    ISNULL(SUM(CASE WHEN sitem.FNUMBER = 'TD05' THEN fas.FMoney ELSE 0 END), 0) AS hardship_subsidy ,\n");
+    	// 7. 社保公积金补贴 = 社保公积金补贴
+    	sql.append("    ISNULL(SUM(CASE WHEN sitem.FNUMBER = 'TD101' THEN fas.FMoney ELSE 0 END), 0) AS social_fund \n");
+    	
+    	// -------------------------- FROM子句 --------------------------
+    	// 表关联逻辑:
+    	// 1. T_bd_Person(人员表)关联T_HR_EmpLaborRelation(用工关系表):取入职日期
+    	// 2. 人员表关联T_HR_SFixAdjustSalary(固定薪资调整表):取薪资金额
+    	// 3. 薪资表关联T_HR_SCmpItem(薪资项目表):按薪资项目编码过滤
+    	// 4. 人员表关联T_HR_EmployeeContract(员工合同表):关联甲方信息
+    	// 5. 合同表关联T_HR_LabContractFirstParty(合同甲方表):取甲方名称
+    	sql.append("FROM \n");
+    	sql.append("    T_bd_Person person \n");
+    	sql.append("LEFT JOIN T_HR_EmpLaborRelation elation on person.fid = elation.FPersonID \n");
+    	sql.append("LEFT JOIN T_HR_SFixAdjustSalary fas ON person.FID = fas.FPersonID\n");
+    	sql.append("LEFT JOIN T_HR_SCmpItem sitem ON fas.FCmpItemID = sitem.FID\n");
+    	sql.append("LEFT JOIN T_HR_EmployeeContract econtract on econtract.FEmployeeID = person.FID\n");
+    	sql.append("LEFT JOIN T_HR_LabContractFirstParty firstParty on econtract.FContFirstPartyID = firstParty.FID \n");
+    	
+ 
+    	sql.append("WHERE \n");
+    	sql.append("    sitem.FNUMBER IN ('TD01', 'T012', 'T013', 'TD02', 'TD04', 'TD74', 'T014', 'TD05', 'TD101') \n");
+    	sql.append("    and fas.FLeffectDay = '2199-12-31 00:00:00' \n");
+        
+        BOSUuid read = BOSUuid.read(id);
+        BOSObjectType type = read.getType();
+    	 if (type.toString().equals("7BD37592")){//id类型为合同
+         	sql.append("and  person.fid  in (select FEmployeeID from T_HR_EmployeeContract where fid = '"+id+"')" ) ;
+         }else  if (type.toString().equals("80EF7DED")){//id类型为员工felse
+         	sql.append("and person.fid = '"+id+"'");
+         }
+    	sql.append("GROUP BY \n");
+    	sql.append("    person.FID, person.FNAME_L2 , elation.FEnterDate , person.FIDCardNO , firstParty.FName_l2 \n");
+    	
+    	// -------------------------- ORDER BY子句 --------------------------
+    	// 排序规则:按人员姓名升序排列
+    	sql.append("ORDER BY \n");
+    	sql.append("    person.FNAME_L2");
+    	
+    	System.out.print("osfsql"+sql.toString());
+    	return sql.toString();
+    }
+//	/**
+//     * 执行SQL查询并将结果封装为JSON对象
+//     *
+//     * @param sql     要执行的查询SQL
+//     * @param context 上下文对象
+//     * @param entrys  字段映射明细集合
+//     * @return 封装后的JSON对象,包含电子签模板各字段信息
+//     */
+//    public JSONObject getData(String sql, Context context, FieldMappingEntryCollection entrys) {
+//        // 创建JSON对象用于存储最终封装的数据
+//        JSONObject jsonObject = new JSONObject();
+//        try {
+//            // 执行SQL查询,获取结果集
+//            IRowSet iRowSet1 = DBUtil.executeQuery(context, sql);
+//            // 遍历结果集中的每一行数据
+//				while (iRowSet1.next()) {
+//				    // 遍历每个字段映射明细项
+//				    for (int i = 0; i < entrys.size(); i++) {
+//				        // 获取当前索引对应的字段映射明细信息
+//				        FieldMappingEntryInfo fieldMappingEntryInfo = entrys.get(i);
+//				        // 获取明细项中关联的电子签模板字段信息
+//				        ESignTemplateFileEntryFieldInfo eField = fieldMappingEntryInfo.getEField();
+//				        // 判断该字段是否无效(已废弃)
+//				        boolean invalid = eField.isInvalid();
+//				        // 若字段无效,跳过当前循环(不处理)
+//				        if (invalid) {
+//				            continue;
+//				        }
+//				        // 获取明细项中关联的电子签模板明细信息
+//				        ESignTemplateFileEntryInfo template = fieldMappingEntryInfo.getTemplate();
+//				        // 获取电子签模板的ID
+//				        String eSignTemplateId = template.getESignTemplateId();
+//				        // 从JSON对象中获取该模板ID对应的子JSON对象
+//				        JSONObject templateJSON = jsonObject.getJSONObject(eSignTemplateId);
+//				        // 若模板对应的子JSON对象不存在,则创建并初始化(设置ID和名称)
+//				        if (templateJSON == null) {
+//				            templateJSON = new JSONObject();
+//				            templateJSON.put("id", eSignTemplateId); // 设置模板ID
+//				            templateJSON.put("name", template.getName()); // 设置模板名称
+//				            jsonObject.put(eSignTemplateId, templateJSON); // 将模板信息存入主JSON对象
+//				        }
+//				        // 从模板子JSON对象中获取字段信息对应的子JSON对象
+//				        JSONObject fields = templateJSON.getJSONObject("fields");
+//				        // 若字段信息子JSON对象不存在,则创建并添加到模板子JSON中
+//				        if (fields == null) {
+//				            fields = new JSONObject();
+//				            templateJSON.put("fields", fields);
+//				        }
+//				        // 获取电子签模板字段的ID
+//				        String templateFieldId = eField.getTemplateFieldId();
+//				        // 创建用于存储字段值信息的JSON对象
+//				        JSONObject value = new JSONObject();
+//				        value.put("name", eField.getTemplateFieldName()); // 设置字段名称
+//				        // 获取明细项中关联的数据源字段信息
+//				        //DataConfigSelectFieldEntryInfo dataSourceField = fieldMappingEntryInfo.getDataSourceField();
+////                    if (dataSourceField==null){
+////                        value.put("value","");
+////                        value.put("dataFormat", eField.getDataFormat());
+////                    }else {
+//				        // 获取数据源字段的映射键(对应数据库列名)
+//				        String name = fieldMappingEntryInfo.getEFieldMark();
+//				        // 去除映射键中的双引号(处理可能的格式问题)
+//				        //name = name.replace("\"", "");
+//				        // 从结果集中获取该字段对应的值,并存入字段值JSON对象
+//				        if (name != null && !name.equals("")) {
+//				            try {
+//								value.put("value", iRowSet1.getObject(name));
+//							} catch (SQLException e) {
+//								e.printStackTrace();
+//							}
+//				        }
+//				        // 设置字段的数据类型(取自数据源字段的类型别名)
+//				        //value.put("dataType", dataSourceField.getDataType().getAlias());
+////                    if (dataSourceField.getDataType().getAlias().equals("Date")) {
+////                        Object object = iRowSet1.getObject(name);
+////                        if (object != null) {
+////                            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
+////                            value.put("value", simpleDateFormat.format(iRowSet1.getDate(name)));
+////                        }
+////                        value.put("dataFormat", eField.getDataFormat());
+////                    }
+//				        //}
+//				        if (eField.getComponentType().getValue() == 6 || eField.getComponentType().getValue() == 106) {
+//				            value.put("positionX", eField.getPositionX());
+//				            value.put("positionY", eField.getPositionY());
+//				            value.put("pageNum", eField.getPageNum());
+//				        }
+//				        // 将字段值信息存入字段信息子JSON对象(以模板字段ID为键)
+//				        fields.put(templateFieldId, value);
+//				    }
+//				}
+//
+//
+//        } catch (BOSException e) {
+//            // BOS异常时,封装为运行时异常抛出
+//            throw new RuntimeException(e);
+//        } catch (SQLException e) {
+//            // SQL异常时,封装为运行时异常抛出
+//            throw new RuntimeException(e);
+//        }
+//        // 返回封装好的JSON对象
+//        return jsonObject;
+//    }
 
      
 }

+ 0 - 4
websrc/com/kingdee/eas/custom/esign/service/OtherESignConfigDataService.java

@@ -13,10 +13,6 @@ import com.kingdee.bos.sql.ParserException;
 import com.kingdee.bos.util.BOSObjectType;
 import com.kingdee.bos.util.BOSUuid;
 import com.kingdee.eas.common.EASBizException;
-import com.kingdee.eas.custom.dataconfig.utils.SqlUtils;
-import com.kingdee.eas.custom.entryconfig.DataConfigInfo;
-import com.kingdee.eas.custom.entryconfig.DataConfigSelectFieldEntryCollection;
-import com.kingdee.eas.custom.entryconfig.DataConfigSelectFieldEntryInfo;
 import com.kingdee.eas.custom.esign.*;
 import com.kingdee.eas.custom.esign.bizEnum.ComponentTypeEnum;
 import com.kingdee.eas.custom.esign.utils.ESignFieldMappingUtils;

+ 0 - 1
websrc/com/kingdee/eas/custom/webbeisen/handler/OrgUnitListHandlerEx.java

@@ -69,6 +69,5 @@ public class OrgUnitListHandlerEx extends OrgUnitListHandler {
         batchMessageTipsHeader.setFailureCount(failure);
         batchMessageTipsHeader.setSuccessCount(sucess);
         JSONUtils.SUCCESS(batchMessageTipsHeader);
-
     }
 }

+ 10 - 4
websrc/com/kingdee/eas/custom/webbeisen/test/BeiSenSysTest.java

@@ -1128,10 +1128,16 @@ public class BeiSenSysTest implements IHRMsfService {
         }
     }
 
-    public static void main(String[] args) {
-        String name = extractFileNameFromUrl("https://dfiles.italent.cn/download/recruitonboardingfile/433107/1753067254/3/66304e3e5cb7431f9fb1900ba675cee3.jpg?sig_t=1753070295&sig_exp=2592000&sig_a=recruitonboarding&sig_pm=8&sig_npm=2&sig_v=1&sig=41d7e3c49cef36421ff8c4c4bd4ff6b145810ca3");
-        System.out.println(name);
-    }
+//    public static void main(String[] args) {
+//        String name = extractFileNameFromUrl("https://dfiles.italent.cn/download/recruitonboardingfile/433107/1753067254/3/66304e3e5cb7431f9fb1900ba675cee3.jpg?sig_t=1753070295&sig_exp=2592000&sig_a=recruitonboarding&sig_pm=8&sig_npm=2&sig_v=1&sig=41d7e3c49cef36421ff8c4c4bd4ff6b145810ca3");
+//        System.out.println(name);
+//    }
+public static void main(String[] args) {
+    String tiem = "2025-05-01 00:00:00.00.0";
+    String substring = tiem.substring(0, 19);
+    System.out.println(substring);
+}
+
 
     // ´ÓURLÖÐÌáÈ¡ÎļþÃû
     private static String extractFileNameFromUrl(String url) {

+ 939 - 0
websrc/com/kingdee/eas/custom/webbeisen/thirdpartysystemsyn/utils/AssistSynchronizingUtils.java

@@ -0,0 +1,939 @@
+package com.kingdee.eas.custom.webbeisen.thirdpartysystemsyn.utils;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.kingdee.bos.BOSException;
+import com.kingdee.bos.BOSObjectFactory;
+import com.kingdee.bos.Context;
+import com.kingdee.bos.dao.IObjectCollection;
+import com.kingdee.bos.dao.IObjectValue;
+import com.kingdee.bos.dao.query.IQueryExecutor;
+import com.kingdee.bos.dao.query.QueryExecutorFactory;
+import com.kingdee.bos.metadata.MetaDataPK;
+import com.kingdee.bos.metadata.data.SortType;
+import com.kingdee.bos.metadata.entity.*;
+import com.kingdee.bos.metadata.query.util.CompareType;
+import com.kingdee.bos.sql.ParserException;
+import com.kingdee.bos.util.BOSObjectType;
+import com.kingdee.bos.util.BOSUuid;
+import com.kingdee.eas.common.EASBizException;
+import com.kingdee.eas.custom.thirdpartysystemsyn.config.viewconfig.*;
+import com.kingdee.eas.custom.thirdpartysystemsyn.enumerationset.DataTypeEnum;
+import com.kingdee.eas.custom.thirdpartysystemsyn.enumerationset.EntityAttributeEnum;
+import com.kingdee.eas.framework.CoreBaseCollection;
+import com.kingdee.eas.framework.CoreBaseInfo;
+import com.kingdee.eas.framework.ICoreBase;
+import com.kingdee.shr.attachment.SHRAttachmentExtCollection;
+import com.kingdee.shr.attachment.SHRAttachmentExtFactory;
+import com.kingdee.shr.attachment.SHRAttachmentExtInfo;
+import com.kingdee.shr.base.syssetting.MSFServiceFacadeFactory;
+import com.kingdee.shr.base.syssetting.context.SHRContext;
+import com.kingdee.shr.base.syssetting.exception.SHRWebException;
+import com.kingdee.shr.base.syssetting.exception.ShrWebBizException;
+import com.kingdee.shr.base.syssetting.model.VirtualDataFetcher;
+import com.kingdee.shr.base.syssetting.util.MetaDataUtil;
+import com.kingdee.util.Uuid;
+import com.kingdee.util.enums.EnumUtils;
+import org.apache.log4j.Logger;
+
+import java.util.*;
+
+public class AssistSynchronizingUtils {
+    // 日志记录器,用于记录系统操作日志
+    private static final Logger logger = Logger.getLogger("com.kingdee.eas.custom.webbeisen.thirdpartysystemsyn.utils.AssistSynchronizingUtils");
+
+    /**
+     * 重写父类方法,根据配置编号和过滤条件获取数据
+     * 该方法主要执行以下步骤:
+     * 1. 解析过滤条件JSON字符串
+     * 2. 获取头部配置信息
+     * 3. 构建查询条件并执行查询
+     * 4. 处理查询结果并转换为JSON格式
+     * 5. 处理分录数据(如果存在)
+     *
+     * @param ctx 上下文对象
+     * @param configNumber 配置编号,用于定位具体的同步配置
+     * @param filterInfos 过滤条件信息,JSON格式字符串
+     * @return 处理后的结果数据,JSON格式字符串
+     * @throws BOSException 当操作过程中发生业务异常时抛出
+     */
+    public JSONArray getData(Context ctx, String configNumber, String filterInfos) throws BOSException {
+        // 记录方法调用日志,包含入参信息
+        logger.info("Starting getData method with configNumber: " + configNumber + ", filterInfos: " + filterInfos);
+
+        // 用于记录处理统计信息
+        int totalRecords = 0;
+        int successRecords = 0;
+        int failedRecords = 0;
+        JSONArray errorDetails = new JSONArray();
+
+        // 解析过滤条件JSON字符串为JSONObject
+        JSONObject jsonObject = JSONObject.parseObject(filterInfos);
+        JSONArray resultArray = new JSONArray(); // 创建结果数组
+
+        try {
+            // 获取头部配置信息
+            logger.debug("Getting head configuration for configNumber: " + configNumber);
+            EntityViewInfo headEntry = createEntityViewInfo(configNumber, EntityAttributeEnum.HEAD_VALUE);
+            ConfigInfoEntryCollection entries = ConfigInfoEntryFactory.getLocalInstance(ctx).getConfigInfoEntryCollection(headEntry);
+
+            // 验证条目信息是否唯一
+            if (entries.size() != 1) {
+                String errorMsg = "头部信息配置异常,期望1条配置但找到" + entries.size() + "条";
+                logger.error(errorMsg);
+                throw new RuntimeException(errorMsg); // 抛出配置异常
+            }
+
+            // 获取唯一的条目信息
+            ConfigInfoEntryInfo configInfoEntryInfo = entries.get(0);
+            String entityName = configInfoEntryInfo.getEntityName(); // 获取实体名称
+            logger.debug("Found entity: " + entityName + " for configNumber: " + configNumber);
+
+            // 创建实体查询视图并设置查询条件
+            EntityViewInfo headEntityViewInfo = new EntityViewInfo();
+            String filterExpr = jsonObject.getString(entityName); // 获取实体对应的过滤条件
+            if (filterExpr != null && !filterExpr.trim().isEmpty()) { // 检查过滤条件是否非空
+                headEntityViewInfo.setFilter(filterExpr); // 设置过滤条件
+                logger.debug("Set filter for entity " + entityName + ": " + filterExpr);
+            }
+
+            // 设置查询字段
+            ConfigInfoEntryFieldCollection fields = configInfoEntryInfo.getFields();
+            SelectorItemCollection selectorItem = getSelectorItem(fields); // 获取选择器项目
+            headEntityViewInfo.setSelector(selectorItem); // 设置选择器
+            logger.debug("Set selector with " + selectorItem.size() + " fields");
+
+            // 设置排序
+            String sortField = configInfoEntryInfo.getSortField(); // 获取排序字段
+            SorterItemCollection sorterItemCollection = sorterProcessing(sortField); // 处理排序字段
+            if (sorterItemCollection != null) {
+                headEntityViewInfo.setSorter(sorterItemCollection); // 设置排序器
+                logger.debug("Set sorter with " + sorterItemCollection.size() + " fields");
+            }
+
+            // 执行查询获取数据集合
+            boolean isQuery = configInfoEntryInfo.isIsQuery(); // 判断是否为查询类型
+            CoreBaseCollection collection; // 声明数据集合
+            if (isQuery) {
+                logger.debug("Initializing collection using query for entity: " + entityName);
+                collection = this.initCollection(entityName, headEntityViewInfo, ctx); // 初始化集合
+            } else {
+                String bosType = configInfoEntryInfo.getBosType(); // 获取BOS类型
+                BOSObjectType bosObjectType = BOSObjectType.create(bosType); // 创建BOS对象类型
+                logger.debug("Getting collection using BOS object type: " + bosType);
+                // 根据BOS类型创建对应的业务对象实例
+                ICoreBase bosObject = (ICoreBase) BOSObjectFactory.createBOSObject(ctx, bosObjectType);
+                collection = bosObject.getCollection(headEntityViewInfo); // 获取数据集合
+            }
+
+            totalRecords = collection.size();
+            logger.info("Retrieved " + totalRecords + " records for processing");
+
+            // 处理查询结果
+            processCollectionData(ctx, configNumber, jsonObject, resultArray, collection,
+                    configInfoEntryInfo, fields, errorDetails);
+
+            successRecords = resultArray.size();
+            failedRecords = totalRecords - successRecords;
+
+            logger.info("Data processing completed. Success: " + successRecords +
+                    ", Failed: " + failedRecords + ", Total: " + totalRecords);
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            String errorMsg = "Error occurred while getting data for configNumber: " + configNumber;
+            logger.error(errorMsg, e);
+
+            // 创建错误详情记录
+            JSONObject errorDetail = new JSONObject();
+            errorDetail.put("configNumber", configNumber);
+            errorDetail.put("errorType", "MAIN_PROCESS_ERROR");
+            errorDetail.put("errorMessage", e.getMessage());
+            errorDetail.put("stackTrace", Arrays.toString(e.getStackTrace()));
+            errorDetails.add(errorDetail);
+
+            failedRecords = totalRecords; // 所有记录都标记为失败
+            successRecords = 0;
+
+            throw new BOSException("数据获取失败: " + e.getMessage(), e); // 抛出业务异常
+        } finally {
+            // 记录最终处理结果统计
+            JSONObject processSummary = new JSONObject();
+            processSummary.put("configNumber", configNumber);
+            processSummary.put("totalRecords", totalRecords);
+            processSummary.put("successRecords", successRecords);
+            processSummary.put("failedRecords", failedRecords);
+            processSummary.put("errorDetails", errorDetails);
+
+            logger.info("Process summary: " + processSummary.toJSONString());
+        }
+
+        logger.info("Successfully retrieved data, result size: " + resultArray.size());
+        return resultArray;
+    }
+
+
+    public void saveData(Context ctx, String configNumber, String controllerBeanEx) throws BOSException {
+        EntityViewInfo headEntry = createEntityViewInfo(configNumber, EntityAttributeEnum.HEAD_VALUE);
+        ConfigInfoEntryCollection entries = ConfigInfoEntryFactory.getLocalInstance(ctx).getConfigInfoEntryCollection(headEntry);
+
+        // 验证条目信息是否唯一
+        if (entries.size() != 1) {
+            String errorMsg = "头部信息配置异常,期望1条配置但找到" + entries.size() + "条";
+            logger.error(errorMsg);
+            throw new RuntimeException(errorMsg); // 抛出配置异常
+        }
+
+        // 获取唯一的条目信息
+        ConfigInfoEntryInfo configInfoEntryInfo = entries.get(0);
+        String entityName = configInfoEntryInfo.getEntityName(); // 获取实体名称
+        logger.debug("Found entity: " + entityName + " for configNumber: " + configNumber);
+        ConfigInfoInfo parent = configInfoEntryInfo.getParent();
+        //osf服务名
+        String osfName = parent.getOsfName();
+        String osfParam = parent.getOsfParam();
+        Object o = null;
+        try {
+            o = MSFServiceFacadeFactory.getLocalInstance(ctx).processService(osfName, this.getOSFParam(osfParam));
+
+        } catch (EASBizException e) {
+            throw new RuntimeException(e);
+        }
+        JSONArray osfReturnData = JSONArray.parseArray(o.toString());
+        for (int i = 0; i < osfReturnData.size(); i++) {
+            JSONObject osfReturnDataEntry = osfReturnData.getJSONObject(i);
+            //处理头部信息
+            boolean isCreateData = configInfoEntryInfo.isIsCreateData();//是否创建数据
+
+            String thirdUniqueValue = configInfoEntryInfo.getThirdUniqueValue();//第三方唯一值
+            String hrUniqueValue = configInfoEntryInfo.getHrUniqueValue();//hr唯一值
+            String bosType = configInfoEntryInfo.getBosType();
+            Class objectValueClass1 = null;
+            try {
+                objectValueClass1 = MetaDataUtil.getObjectValueClass(entityName);
+                // 创建对应的实体对象
+                CoreBaseInfo coreBaseInfo = (CoreBaseInfo) MetaDataUtil.newInstance(objectValueClass1, entityName);
+                if (!isCreateData){
+                    String value = getThirdUniqueValue(osfReturnDataEntry, thirdUniqueValue);
+                    if (value!=null){
+                        CoreBaseInfo coreBaseInfo1 = findCoreBaseInfo(ctx, coreBaseInfo.getBOSType(), value, hrUniqueValue);
+                        if (coreBaseInfo1!=null){
+                            coreBaseInfo = coreBaseInfo1;
+                        }
+                    }
+                }
+            } catch (ShrWebBizException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+    public String getThirdUniqueValue(JSONObject jsonObject,String thirdUniqueValue){
+        String[] split = thirdUniqueValue.split("\\.");
+        Object value = null;
+        for (int i = 0; i < split.length; i++) {
+            String s = split[i];
+            value = jsonObject.get(s);
+            if (value instanceof JSONArray){
+                JSONArray jsonArray = jsonObject.getJSONArray(s);
+                value = jsonArray.get(0);
+            }
+        }
+        return value==null?null:value.toString();
+    }
+
+
+    public CoreBaseInfo findCoreBaseInfo(Context ctx,BOSObjectType bosObjectType,
+                                         String thirdUniqueValue,
+                                         String hrUniqueValue) throws BOSException {
+
+        ICoreBase bosObject =  (ICoreBase) (BOSObjectFactory.createBOSObject(ctx,bosObjectType));
+        CoreBaseCollection collection = bosObject.getCollection("where " + hrUniqueValue + " = '" + thirdUniqueValue + "' ");
+        if (collection.size()>1){
+            throw new RuntimeException("");
+        } else if (collection.size()==0) {
+            return null;
+        }else {
+            return collection.get(0);
+        }
+    }
+
+    public Map<String,Object> getOSFParam(String jsonData){
+        if (jsonData!=null&&!jsonData.equals("")){
+            JSONObject param = JSONObject.parseObject(jsonData);
+            Set<String> strings = param.keySet();
+            Iterator<String> iterator = strings.iterator();
+            Map<String,Object> map = new HashMap<String,Object>();
+            while (iterator.hasNext()){
+                String next = iterator.next();
+                map.put(next,param.get(next));
+            }
+            return map;
+        }else {
+            return null;
+        }
+    }
+
+    /**
+     * 处理查询结果集合数据
+     * 遍历集合中的每个CoreBaseInfo对象,将其转换为JSON格式,并处理相关的分录数据
+     *
+     * @param ctx 上下文对象
+     * @param configNumber 配置编号
+     * @param jsonObject 过滤条件JSON对象
+     * @param resultArray 结果数组
+     * @param collection 查询结果集合
+     * @param configInfoEntryInfo 配置条目信息
+     * @param fields 字段配置集合
+     * @param errorDetails 错误详情数组,用于记录处理过程中的错误
+     * @throws BOSException 业务异常
+     * @throws ClassNotFoundException 类未找到异常
+     * @throws ParserException 解析异常
+     * @throws SHRWebException SHR Web异常
+     */
+    public void processCollectionData(Context ctx, String configNumber, JSONObject jsonObject,
+                                      JSONArray resultArray, CoreBaseCollection collection,
+                                      ConfigInfoEntryInfo configInfoEntryInfo,
+                                      ConfigInfoEntryFieldCollection fields,
+                                      JSONArray errorDetails)
+            throws BOSException, ClassNotFoundException, ParserException, SHRWebException {
+        for (int i = 0; i < collection.size(); i++) { // 遍历集合中的每个元素
+            String recordId = "unknown";
+            try {
+                CoreBaseInfo coreBaseInfo = collection.get(i); // 获取当前元素
+                recordId = coreBaseInfo.getId() != null ? coreBaseInfo.getId().toString() : "unknown";
+                logger.debug("Processing record " + (i+1) + "/" + collection.size() + ", ID: " + recordId);
+                JSONObject resultData = new JSONObject(); // 创建结果数据对象
+                JSONObject mainData = new JSONObject(); // 创建主数据对象
+                // 处理单条数据,转换为JSON格式
+                dataProcessing(mainData, coreBaseInfo, fields, recordId, ctx);
+                String name = configInfoEntryInfo.getName(); // 获取配置名称
+                resultData.put(name, mainData); // 将主数据添加到结果数据
+                // 处理分录数据
+                processEntryData(ctx, configNumber, jsonObject, resultData, coreBaseInfo, recordId, errorDetails);
+                resultArray.add(resultData); // 将结果数据添加到结果数组
+                logger.debug("Successfully processed record ID: " + recordId);
+            } catch (Exception e) {
+                e.printStackTrace();
+                String errorMsg = "Error processing record " + (i+1) + "/" + collection.size() + ", ID: " + recordId;
+                logger.error(errorMsg, e);
+                // 创建错误详情记录
+                JSONObject errorDetail = new JSONObject();
+                errorDetail.put("configNumber", configNumber);
+                errorDetail.put("recordId", recordId);
+                errorDetail.put("recordIndex", i);
+                errorDetail.put("errorType", "RECORD_PROCESSING_ERROR");
+                errorDetail.put("errorMessage", e.getMessage());
+                errorDetail.put("stackTrace", Arrays.toString(e.getStackTrace()));
+                errorDetails.add(errorDetail);
+                // 继续处理下一条记录
+                continue;
+            }
+        }
+    }
+
+    /**
+     * 处理分录数据
+     * 获取配置中的分录信息,根据关联字段查询相关的分录数据,并将其转换为JSON格式
+     *
+     * @param ctx 上下文对象
+     * @param configNumber 配置编号
+     * @param jsonObject 过滤条件JSON对象
+     * @param resultData 结果数据对象
+     * @param coreBaseInfo 核心基础信息对象
+     * @param recordId 当前处理的主记录ID
+     * @param errorDetails 错误详情数组,用于记录处理过程中的错误
+     * @throws BOSException 业务异常
+     * @throws ClassNotFoundException 类未找到异常
+     * @throws ParserException 解析异常
+     * @throws SHRWebException SHR Web异常
+     */
+    public void processEntryData(Context ctx, String configNumber, JSONObject jsonObject,
+                                 JSONObject resultData, CoreBaseInfo coreBaseInfo,
+                                 String recordId, JSONArray errorDetails)
+            throws BOSException, ClassNotFoundException, ParserException, SHRWebException {
+        try {
+            // 获取分录为 boy类型的配置
+            EntityViewInfo boyEntry = createEntityViewInfo(configNumber, EntityAttributeEnum.BOY_VALUE);
+            ConfigInfoEntryCollection entryCollection = ConfigInfoEntryFactory.getLocalInstance(ctx).getConfigInfoEntryCollection(boyEntry);
+
+            for (int j = 0; j < entryCollection.size(); j++) { // 遍历分录配置集合
+                ConfigInfoEntryInfo configInfoEntryInfo1 = entryCollection.get(j); // 获取当前分录配置
+                String boyEntityName = configInfoEntryInfo1.getEntityName(); // 获取分录实体名称
+                ConfigInfoEntryFieldCollection boyFields = configInfoEntryInfo1.getFields(); // 获取分录字段配置
+                logger.debug("Processing entry data for entity: " + boyEntityName + ", main record ID: " + recordId);
+                // 创建分录查询视图
+                EntityViewInfo boyEntityViewInfo = new EntityViewInfo();
+                String boyFilterExpr = jsonObject.getString(boyEntityName); // 获取分录过滤条件
+                // 设置关联字段过滤条件
+                String crelatedField = configInfoEntryInfo1.getCrelatedField(); // 获取关联字段
+                FilterInfo filter = new FilterInfo(); // 创建过滤器
+                String id = coreBaseInfo.getId().toString(); // 获取主数据ID
+                filter.getFilterItems().add(new FilterItemInfo(crelatedField, id, CompareType.EQUALS)); // 添加关联字段过滤条件
+                if (boyFilterExpr != null && !boyFilterExpr.trim().isEmpty()) { // 检查分录过滤条件是否非空
+                    filter.getFilterItems().add(new FilterItemInfo(boyFilterExpr)); // 添加分录过滤条件
+                }
+                boyEntityViewInfo.setFilter(filter); // 设置过滤器
+                // 设置查询字段
+                SelectorItemCollection boySelectorItem = getSelectorItem(boyFields); // 获取分录选择器
+                boyEntityViewInfo.setSelector(boySelectorItem); // 设置选择器
+                // 执行查询获取分录数据
+                boolean isQuery1 = configInfoEntryInfo1.isIsQuery(); // 判断是否为查询类型
+                CoreBaseCollection boyCollection; // 声明分录数据集合
+                if (isQuery1) {
+                    boyCollection = this.initCollection(boyEntityName, boyEntityViewInfo, ctx); // 初始化分录集合
+                } else {
+                    String boyDosType = configInfoEntryInfo1.getBosType(); // 获取分录BOS类型
+                    BOSObjectType boyBosObjectType = BOSObjectType.create(boyDosType); // 创建BOS对象类型
+                    ICoreBase boyBosObject = (ICoreBase) BOSObjectFactory.createBOSObject(ctx, boyBosObjectType); // 创建业务对象
+                    boyCollection = boyBosObject.getCollection(boyEntityViewInfo); // 获取分录数据集合
+                }
+                logger.debug("Retrieved " + boyCollection.size() + " entry records for entity: " +
+                        boyEntityName + ", main record ID: " + recordId);
+                // 处理分录数据
+                JSONArray entryDataArray = new JSONArray(); // 创建分录数据数组
+                for (int k = 0; k < boyCollection.size(); k++) { // 遍历分录数据集合
+                    try {
+                        CoreBaseInfo coreBaseInfo1 = boyCollection.get(k); // 获取当前分录数据
+                        String entryRecordId = coreBaseInfo1.getId() != null ? coreBaseInfo1.getId().toString() : "unknown";
+
+                        JSONObject entryData = new JSONObject(); // 创建分录数据对象
+                        dataProcessing(entryData, coreBaseInfo1, boyFields, entryRecordId, ctx); // 处理分录数据
+                        entryDataArray.add(entryData); // 将分录数据添加到数组
+
+                        logger.debug("Processed entry record " + (k+1) + "/" + boyCollection.size() +
+                                ", ID: " + entryRecordId + " for main record ID: " + recordId);
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                        String errorMsg = "Error processing entry record " + (k+1) + "/" + boyCollection.size() +
+                                " for main record ID: " + recordId;
+                        logger.error(errorMsg, e);
+
+                        // 创建错误详情记录
+                        JSONObject errorDetail = new JSONObject();
+                        errorDetail.put("configNumber", configNumber);
+                        errorDetail.put("mainRecordId", recordId);
+                        errorDetail.put("entryEntity", boyEntityName);
+                        errorDetail.put("entryIndex", k);
+                        errorDetail.put("errorType", "ENTRY_RECORD_PROCESSING_ERROR");
+                        errorDetail.put("errorMessage", e.getMessage());
+                        errorDetail.put("stackTrace", Arrays.toString(e.getStackTrace()));
+                        errorDetails.add(errorDetail);
+                        // 继续处理下一条分录记录
+                        continue;
+                    }
+                }
+                String name1 = configInfoEntryInfo1.getName(); // 获取分录配置名称
+                resultData.put(name1, entryDataArray); // 将分录数据添加到结果数据
+                logger.debug("Completed processing entry data for entity: " + boyEntityName +
+                        ", main record ID: " + recordId + ", records: " + entryDataArray.size());
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            String errorMsg = "Error processing entry data for main record ID: " + recordId;
+            logger.error(errorMsg, e);
+            // 创建错误详情记录
+            JSONObject errorDetail = new JSONObject();
+            errorDetail.put("configNumber", configNumber);
+            errorDetail.put("mainRecordId", recordId);
+            errorDetail.put("errorType", "ENTRY_PROCESSING_ERROR");
+            errorDetail.put("errorMessage", e.getMessage());
+            errorDetail.put("stackTrace", Arrays.toString(e.getStackTrace()));
+            errorDetails.add(errorDetail);
+            // 抛出异常,由上层处理
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * 处理单条CoreBaseInfo数据,将其字段信息转换为JSONObject
+     * 根据字段类型的不同,采用不同的处理方式:
+     * 1. 枚举类型:获取枚举列表和当前值的别名
+     * 2. 对象值类型:提取对象的名称和编号
+     * 3. 对象集合类型:提取集合中每个对象的名称和编号
+     * 4. 其他类型:直接使用字段值
+     * 5. 最后处理附件信息
+     *
+     * @param jsonObject 用于存储处理后数据的JSON对象
+     * @param coreBaseInfo 待处理的业务数据对象
+     * @param fieldCollection 配置的字段集合,包含需要处理的字段信息
+     * @param recordId 当前处理的记录ID,用于日志记录
+     * @param context 上下文对象,用于获取附件信息
+     * @throws ClassNotFoundException 当枚举类找不到时抛出
+     */
+    public void dataProcessing(JSONObject jsonObject, CoreBaseInfo coreBaseInfo,
+                               ConfigInfoEntryFieldCollection fieldCollection, String recordId, Context context)
+            throws ClassNotFoundException {
+        for (int i = 0; i < fieldCollection.size(); i++) { // 遍历字段配置集合
+            String fieldName = "unknown";
+
+            try {
+                ConfigInfoEntryFieldInfo configInfoEntryFieldInfo = fieldCollection.get(i); // 获取当前字段配置
+                ConfigInfoEntryInfo parent = configInfoEntryFieldInfo.getParent1(); // 获取父配置信息
+                fieldName = configInfoEntryFieldInfo.getFieldName(); // 获取字段名称
+                Object fieldValue = coreBaseInfo.get(fieldName); // 获取字段值
+                logger.debug("Processing field: " + fieldName + " for record ID: " + recordId);
+                // 封装字段信息为JSON对象
+                JSONObject fieldJson = createFieldJson(configInfoEntryFieldInfo, fieldValue);
+                // 将字段JSON对象存入结果JSON中
+                jsonObject.put(fieldName, fieldJson);
+                logger.debug("Successfully processed field: " + fieldName + " for record ID: " + recordId);
+            } catch (Exception e) {
+                e.printStackTrace();
+                String errorMsg = "Error processing field: " + fieldName + " for record ID: " + recordId;
+                logger.error(errorMsg, e);
+                // 创建错误字段标记
+                JSONObject errorField = new JSONObject();
+                errorField.put("fieldName", fieldName);
+                errorField.put("error", true);
+                errorField.put("errorMessage", e.getMessage());
+                jsonObject.put(fieldName, errorField);
+                // 继续处理下一个字段
+                continue;
+            }
+        }
+        // 处理附件信息
+        String id = coreBaseInfo.getId().toString();
+        fileProcessor(id, jsonObject, context);
+    }
+
+    /**
+     * 处理业务对象的附件信息
+     * 根据业务对象ID查询关联的附件信息,并将附件详情添加到结果JSON对象中
+     * 该方法通常在dataProcessing方法的最后调用,用于补充附件数据
+     *
+     * 处理流程:
+     * 1. 根据业务ID查询关联的附件信息
+     * 2. 提取附件名称和ID等关键信息
+     * 3. 将附件信息组织成JSON格式并添加到结果集中
+     * 4. 异常情况下记录错误日志并添加错误标记
+     *
+     * @param id 业务对象ID,用于查询关联的附件
+     * @param jsonObject 结果数据集,附件信息将添加到该对象的"file"字段中
+     * @param context 上下文对象,用于获取数据库连接和执行环境
+     */
+    public void fileProcessor(String id, JSONObject jsonObject, Context context) {
+        JSONArray jsonArray = new JSONArray();
+        try {
+            JSONObject file = new JSONObject();
+            // 查询与业务对象ID关联的所有附件信息
+            SHRAttachmentExtCollection shrAttachmentExtCollection = SHRAttachmentExtFactory
+                    .getLocalInstance(context)
+                    .getSHRAttachmentExtCollection("select *,attachment.* where boid = '" + id + "'");
+
+            // 遍历所有附件,提取关键信息
+            for (int i = 0; i < shrAttachmentExtCollection.size(); i++) {
+                SHRAttachmentExtInfo shrAttachmentExtInfo = shrAttachmentExtCollection.get(i);
+                file.put("name", shrAttachmentExtInfo.getName()); // 附件名称
+                file.put("id", shrAttachmentExtInfo.getAttachment().getId().toString()); // 附件ID
+                jsonArray.add(file);
+            }
+
+            // 将附件信息数组添加到结果集
+            jsonObject.put("file", jsonArray);
+        } catch (BOSException e) {
+            e.printStackTrace();
+            // 记录附件处理错误日志
+            String errorMsg = "Error processing file for business object ID: " + id;
+            logger.error(errorMsg, e);
+
+            // 创建错误字段标记,便于前端识别和处理
+            JSONObject errorField = new JSONObject();
+            errorField.put("field", "file");
+            errorField.put("error", true);
+            errorField.put("errorMessage", e.getMessage());
+            jsonObject.put("file", errorField);
+        }
+    }
+
+    /**
+     * 创建字段JSON对象
+     * 包含字段的基本信息(名称、别名、第三方字段名)和类型信息,以及根据类型处理后的字段值
+     *
+     * @param configInfoEntryFieldInfo 配置信息条目字段信息
+     * @param fieldValue 字段值
+     * @return 字段JSON对象
+     * @throws ClassNotFoundException 当枚举类找不到时抛出
+     */
+    public JSONObject createFieldJson(ConfigInfoEntryFieldInfo configInfoEntryFieldInfo, Object fieldValue)
+            throws ClassNotFoundException {
+        JSONObject fieldJson = new JSONObject(); // 创建字段JSON对象
+        String fieldName = configInfoEntryFieldInfo.getFieldName(); // 获取字段名称
+        String fieldAlias = configInfoEntryFieldInfo.getFieldAlias(); // 获取字段别名
+        DataTypeEnum fieldType = configInfoEntryFieldInfo.getFieldType(); // 获取字段类型
+        String thirdField = configInfoEntryFieldInfo.getThirdField(); // 获取第三方字段名
+
+        fieldJson.put("fieldName", fieldName); // 添加字段名称
+        fieldJson.put("fieldAlias", fieldAlias); // 添加字段别名
+        fieldJson.put("thirdField", thirdField); // 添加第三方字段名
+
+        // 添加字段类型信息
+        JSONObject fieldTypeJson = new JSONObject(); // 创建字段类型JSON对象
+        fieldTypeJson.put("alias", fieldType.getAlias()); // 添加类型别名
+        fieldTypeJson.put("name", fieldType.getName()); // 添加类型名称
+        fieldTypeJson.put("value", fieldType.getValue()); // 添加类型值
+        fieldJson.put("fieldType", fieldTypeJson); // 添加字段类型信息
+
+        // 根据字段类型处理字段值
+        processFieldValueByType(configInfoEntryFieldInfo, fieldValue, fieldJson);
+
+        return fieldJson; // 返回字段JSON对象
+    }
+
+    /**
+     * 根据字段类型处理字段值
+     * 针对不同类型的数据采用不同的处理策略,确保数据格式符合预期
+     *
+     * @param configInfoEntryFieldInfo 配置信息条目字段信息
+     * @param fieldValue 字段值
+     * @param fieldJson 字段JSON对象
+     * @throws ClassNotFoundException 当枚举类找不到时抛出
+     */
+    public void processFieldValueByType(ConfigInfoEntryFieldInfo configInfoEntryFieldInfo,
+                                        Object fieldValue, JSONObject fieldJson)
+            throws ClassNotFoundException {
+        DataTypeEnum fieldType = configInfoEntryFieldInfo.getFieldType(); // 获取字段类型
+        String typeAlias = fieldType.getAlias(); // 获取类型别名
+
+        if ("Enum".equals(typeAlias)) { // 处理枚举类型
+            processEnumFieldValue(configInfoEntryFieldInfo, fieldValue, fieldJson);
+        } else if ("ObjectValue".equals(typeAlias)) { // 处理对象值类型
+            processObjectValueFieldValue(fieldValue, fieldJson);
+        } else if ("ObjectCollection".equals(typeAlias)) { // 处理对象集合类型
+            processObjectCollectionFieldValue(fieldValue, fieldJson);
+        } else { // 处理其他类型
+            fieldJson.put("value", fieldValue); // 直接添加字段值
+        }
+    }
+
+    /**
+     * 处理枚举类型字段值
+     * 获取枚举类的所有可能值列表,并将当前字段值转换为对应的枚举别名
+     *
+     * @param configInfoEntryFieldInfo 配置信息条目字段信息
+     * @param fieldValue 字段值
+     * @param fieldJson 字段JSON对象
+     * @throws ClassNotFoundException 当枚举类找不到时抛出
+     */
+    public void processEnumFieldValue(ConfigInfoEntryFieldInfo configInfoEntryFieldInfo,
+                                      Object fieldValue, JSONObject fieldJson)
+            throws ClassNotFoundException {
+        String source = configInfoEntryFieldInfo.getSource(); // 获取枚举源
+        List<?> enumList = EnumUtils.getEnumList(source); // 获取枚举列表
+        fieldJson.put("source", enumList); // 添加枚举源信息
+
+        if (fieldValue != null) { // 检查字段值是否为空
+            Integer value = (Integer) fieldValue; // 转换字段值为整数
+            fieldJson.put("value", EnumUtils.getEnum(Class.forName(source), value).getAlias()); // 添加枚举值别名
+        }
+    }
+
+    /**
+     * 处理对象值类型字段值
+     * 提取对象的名称和编号属性,构建简化的对象表示
+     *
+     * @param fieldValue 字段值
+     * @param fieldJson 字段JSON对象
+     */
+    public void processObjectValueFieldValue(Object fieldValue, JSONObject fieldJson) {
+        if (fieldValue instanceof CoreBaseInfo) { // 检查字段值是否为CoreBaseInfo类型
+            CoreBaseInfo sourceCoreBaseInfo = (CoreBaseInfo) fieldValue; // 转换字段值
+            JSONObject sourceJSONObject = new JSONObject(); // 创建源JSON对象
+            sourceJSONObject.put("name", sourceCoreBaseInfo.get("name")); // 添加名称属性
+            sourceJSONObject.put("number", sourceCoreBaseInfo.get("number")); // 添加编号属性
+            fieldJson.put("value", sourceJSONObject); // 添加源对象信息
+        }
+    }
+
+    /**
+     * 处理对象集合类型字段值
+     * 遍历集合中的每个对象,提取名称和编号属性,构建对象数组
+     *
+     * @param fieldValue 字段值
+     * @param fieldJson 字段JSON对象
+     */
+    public void processObjectCollectionFieldValue(Object fieldValue, JSONObject fieldJson) {
+        if (fieldValue instanceof IObjectCollection) { // 检查字段值是否为对象集合类型
+            IObjectCollection collection = (IObjectCollection) fieldValue; // 转换字段值
+            JSONArray jsonArray = new JSONArray(); // 创建JSON数组
+
+            for (int j = 0; j < collection.size(); j++) { // 遍历集合
+                Object object = collection.getObject(j); // 获取当前对象
+                if (object instanceof CoreBaseInfo) { // 检查对象是否为CoreBaseInfo类型
+                    CoreBaseInfo coreBaseInfo = (CoreBaseInfo) object; // 转换对象
+                    JSONObject sourceJSONObject = new JSONObject(); // 创建源JSON对象
+                    sourceJSONObject.put("name", coreBaseInfo.get("name")); // 添加名称属性
+                    sourceJSONObject.put("number", coreBaseInfo.get("number")); // 添加编号属性
+                    jsonArray.add(sourceJSONObject); // 将源对象添加到数组
+                }
+            }
+
+            fieldJson.put("value", jsonArray); // 添加对象数组
+        }
+    }
+
+    /**
+     * 根据配置的字段集合构建查询选择器,指定查询时需要返回的字段
+     * 对于对象值类型的字段,额外添加相关字段(名称、编号和所有字段)
+     *
+     * @param fields 配置的字段集合
+     * @return 包含所有需要查询的字段的选择器集合
+     */
+    public SelectorItemCollection getSelectorItem(ConfigInfoEntryFieldCollection fields) {
+        SelectorItemCollection selectorItemCollection = new SelectorItemCollection(); // 创建选择器集合
+
+        for (int i = 0; i < fields.size(); i++) { // 遍历字段配置集合
+            ConfigInfoEntryFieldInfo configInfoEntryFieldInfo = fields.get(i); // 获取当前字段配置
+            String fieldName = configInfoEntryFieldInfo.getFieldName(); // 获取字段名称
+            DataTypeEnum fieldType = configInfoEntryFieldInfo.getFieldType(); // 获取字段类型
+
+            // 添加字段到选择器
+            selectorItemCollection.add(fieldName); // 添加字段名称
+
+            // 对于对象值类型,额外添加相关字段
+            if ("ObjectValue".equals(fieldType.getAlias())) { // 检查是否为对象值类型
+                selectorItemCollection.add(fieldName + ".name"); // 添加名称字段
+                selectorItemCollection.add(fieldName + ".number"); // 添加编号字段
+                selectorItemCollection.add(fieldName + ".*"); // 添加所有字段
+            }
+        }
+        selectorItemCollection.add("id"); // 添加ID字段
+        return selectorItemCollection; // 返回选择器集合
+    }
+
+    /**
+     * 创建实体视图查询条件,用于查询配置信息
+     * 根据配置编号和实体属性类型过滤配置信息,并指定需要返回的字段
+     *
+     * @param configNumber 配置编号,用于精确匹配配置
+     * @param type 实体属性类型(如HEAD/ENTRY),用于过滤特定类型的配置
+     * @return 构建好的实体查询视图
+     */
+    public EntityViewInfo createEntityViewInfo(String configNumber, String type) {
+        EntityViewInfo entityViewInfo = new EntityViewInfo(); // 创建实体视图信息
+
+        // 创建过滤条件
+        FilterInfo filterInfo = new FilterInfo(); // 创建过滤器
+        filterInfo.getFilterItems().add(new FilterItemInfo("parent.number", configNumber, CompareType.EQUALS)); // 添加父级编号过滤条件
+        filterInfo.getFilterItems().add(new FilterItemInfo("entityAttribute", type, CompareType.EQUALS)); // 添加实体属性过滤条件
+        entityViewInfo.setFilter(filterInfo); // 设置过滤器
+
+        // 构建查询选择器,指定需要返回的字段
+        SelectorItemCollection selectorItemCollection = new SelectorItemCollection(); // 创建选择器集合
+        selectorItemCollection.add("parent.*"); // 添加父表所有字段
+        selectorItemCollection.add("*"); // 添加条目表所有字段
+        selectorItemCollection.add("Fields.*"); // 添加字段配置表所有字段
+        entityViewInfo.setSelector(selectorItemCollection); // 设置选择器
+
+        return entityViewInfo; // 返回实体视图信息
+    }
+
+    /**
+     * 处理排序字段字符串,转换为排序器集合
+     * 支持以下格式:
+     * 1. "field1 ASC, field2 DESC" - 明确指定排序方向
+     * 2. "field1, field2" - 默认使用升序
+     *
+     * @param sortField 排序字段字符串,格式如 "field1 ASC, field2 DESC"
+     * @return 排序器集合,如果排序字段为空则返回null
+     */
+    public SorterItemCollection sorterProcessing(String sortField) {
+        if (sortField == null || sortField.trim().isEmpty()) { // 检查排序字段是否为空
+            return null; // 返回空值
+        }
+
+        SorterItemCollection sorterItemCollection = new SorterItemCollection(); // 创建排序器集合
+        String[] sortFields = sortField.split(","); // 分割排序字段
+
+        for (String field : sortFields) { // 遍历排序字段数组
+            SorterItemInfo sorterItemInfo = new SorterItemInfo(); // 创建排序器信息
+            String trimmedField = field.trim().toLowerCase(); // 去除空格并转换为小写
+
+            if (trimmedField.contains("asc")) { // 检查是否包含升序关键字
+                String propertyName = trimmedField.replace("asc", "").trim(); // 移除升序关键字
+                sorterItemInfo.setPropertyName(propertyName); // 设置属性名称
+                sorterItemInfo.setSortType(SortType.ASCEND); // 设置升序排序
+            } else if (trimmedField.contains("desc")) { // 检查是否包含降序关键字
+                String propertyName = trimmedField.replace("desc", "").trim(); // 移除降序关键字
+                sorterItemInfo.setPropertyName(propertyName); // 设置属性名称
+                sorterItemInfo.setSortType(SortType.DESCEND); // 设置降序排序
+            } else { // 默认情况
+                sorterItemInfo.setPropertyName(trimmedField); // 设置属性名称
+                sorterItemInfo.setSortType(SortType.ASCEND); // 设置升序排序
+            }
+            sorterItemCollection.add(sorterItemInfo); // 添加排序器到集合
+        }
+
+        return sorterItemCollection; // 返回排序器集合
+    }
+
+    /**
+     * 初始化集合数据
+     * 通过业务接口获取指定实体的数据集合
+     *
+     * @param entityName 实体名称
+     * @param entityViewInfo 实体视图信息
+     * @param context 上下文对象
+     * @return 核心基础集合
+     * @throws SHRWebException SHR Web异常
+     * @throws ParserException 解析异常
+     * @throws BOSException 业务异常
+     */
+    public CoreBaseCollection initCollection(String entityName, EntityViewInfo entityViewInfo, Context context)
+            throws SHRWebException, ParserException, BOSException {
+        IQueryExecutor queryExecutor = this.getQueryExecutor(context, entityViewInfo, entityName); // 获取查询执行器
+        Uuid uuid = queryExecutor.openQuery(); // 打开查询
+        VirtualDataFetcher vdf = VirtualDataFetcher.createInstance(queryExecutor, uuid, 0, 1000); // 创建虚拟数据获取器
+        List<Map<String, Object>> data = vdf.getData(); // 获取数据
+        CoreBaseCollection collection = new CoreBaseCollection(); // 创建核心基础集合
+
+        for (int i = 0; i < data.size(); i++) { // 遍历数据
+            Map<String, Object> stringObjectMap = data.get(i); // 获取当前数据项
+            String string = stringObjectMap.get("id").toString(); // 获取ID字符串
+            BOSUuid read = BOSUuid.read(string); // 读取BOS UUID
+            EntityObjectInfo entityObject = MetaDataUtil.getEntityObjectByBosType(read.getType()); // 获取实体对象信息
+            String fullName = entityObject.getFullName(); // 获取完整类名
+            Class<?> targetClass = MetaDataUtil.getObjectValueClass(fullName); // 获取目标类
+            CoreBaseInfo coreBaseInfo = (CoreBaseInfo) MetaDataUtil.newInstance(targetClass, fullName); // 创建核心基础信息实例
+            SelectorItemCollection selector = entityViewInfo.getSelector(); // 获取选择器
+
+            for (int j = 0; j < selector.size(); j++) { // 遍历选择器
+                SelectorItemInfo selectorItemInfo = selector.get(j); // 获取当前选择器项
+                String propertyName = selectorItemInfo.getPropertyName(); // 获取属性名称
+                coreBaseInfo.put(propertyName, stringObjectMap.get(propertyName)); // 设置属性值
+            }
+            collection.add(coreBaseInfo); // 添加到集合
+        }
+        return collection; // 返回集合
+    }
+
+    /**
+     * 获取查询执行器
+     * 创建并配置查询执行器,用于执行数据查询操作
+     *
+     * @param context 上下文对象
+     * @param entityViewInfo 实体视图信息
+     * @param query 查询字符串
+     * @return 查询执行器
+     * @throws SHRWebException SHR Web异常
+     * @throws ShrWebBizException 业务异常
+     * @throws BOSException 业务异常
+     * @throws ParserException 解析异常
+     */
+    public IQueryExecutor getQueryExecutor(Context context,
+                                           EntityViewInfo entityViewInfo,
+                                           String query) throws SHRWebException, ShrWebBizException, BOSException, ParserException {
+        IQueryExecutor exec = QueryExecutorFactory.getLocalInstance(context, MetaDataPK.create(query)); // 创建查询执行器
+        exec.setObjectView(entityViewInfo); // 设置对象视图
+        exec.option().isIgnoreOrder = true; // 设置忽略排序
+        exec.option().isAutoIgnoreZero = true; // 设置自动忽略零值
+        exec.option().isAutoTranslateBoolean = true; // 设置自动转换布尔值
+        exec.option().isAutoTranslateEnum = true; // 设置自动转换枚举
+        exec.option().isIgnorePermissionCheck = false; // 设置不忽略权限检查
+        return exec; // 返回查询执行器
+    }
+
+    /**
+     * 获取业务接口
+     * 根据实体名称获取对应的业务接口实例
+     *
+     * @param entityName 实体名称
+     * @return 核心基础接口
+     * @throws SHRWebException SHR Web异常
+     */
+    public ICoreBase getBizInterface(String entityName) throws SHRWebException {
+        if (entityName == null) { // 检查实体名称是否为空
+            return null; // 返回空值
+        }
+        try {
+            return MetaDataUtil.getBizInterface(SHRContext.getInstance().getContext(), entityName); // 获取业务接口
+        } catch (BOSException e) {
+            e.printStackTrace();
+            throw new SHRWebException(e); // 抛出SHR Web异常
+        }
+    }
+
+    /**
+     * 给CoreBaseInfo类型对象设置属性值,支持级联属性
+     * 支持"主属性.子属性"格式的属性路径,可以设置嵌套对象的属性值
+     *
+     * @param ctx 上下文对象,用于获取元数据信息
+     * @param coreBaseInfo 要设置属性值的目标对象
+     * @param name 属性名称,支持"主属性.子属性"格式的级联属性
+     * @param value 要设置的属性值
+     * @throws BOSException 当操作过程中发生业务异常时抛出
+     */
+    public void setCoreBaseInfo(Context ctx, IObjectValue coreBaseInfo, String name, Object value) throws BOSException {
+        // 判断是否为级联属性
+        if (name.contains(".")) { // 检查是否包含点号
+            String[] split = name.split("\\."); // 分割属性名称
+            Object parentValue = coreBaseInfo.get(split[0]); // 获取父属性值
+
+            // 获取实体元数据信息
+            EntityObjectInfo entityObject = MetaDataUtil.getEntityObjectByBosType(coreBaseInfo.getBOSType()); // 获取实体对象信息
+            PropertyCollection properties = entityObject.getInheritedNoDuplicatedProperties(); // 获取属性集合
+            PropertyInfo propertyInfo = (PropertyInfo) properties.getObject(split[0]); // 获取属性信息
+            // 处理关联属性
+            if (propertyInfo instanceof LinkPropertyInfo) { // 检查是否为链接属性
+                LinkPropertyInfo linkProperty = (LinkPropertyInfo) propertyInfo; // 转换属性信息
+                RelationshipInfo relationship = linkProperty.getRelationship(); // 获取关系信息
+                String targetFullName = relationship.getSupplierObject().getFullName(); // 获取目标完整名称
+                try {
+                    Class<?> targetClass = MetaDataUtil.getObjectValueClass(targetFullName); // 获取目标类
+                    CoreBaseInfo childObject = getOrCreateChildObject(parentValue, targetClass, targetFullName); // 获取或创建子对象
+                    // 给子对象设置级联属性的子属性值
+                    if (childObject != null) { // 检查子对象是否为空
+                        childObject.put(split[1], value); // 设置子属性值
+                    }
+                } catch (ShrWebBizException e) {
+                    e.printStackTrace();
+                    throw new BOSException("获取目标类失败: " + e.getMessage(), e); // 抛出业务异常
+                }
+            }
+        } else {
+            // 非级联属性,直接设置值
+            coreBaseInfo.put(name, value); // 设置属性值
+        }
+    }
+
+    /**
+     * 获取或创建子对象
+     * 根据父属性值的类型(集合或单个对象),获取现有子对象或创建新的子对象
+     *
+     * @param parentValue 父属性值
+     * @param targetClass 目标类
+     * @param targetFullName 目标全名
+     * @return 子对象
+     */
+    public CoreBaseInfo getOrCreateChildObject(Object parentValue, Class<?> targetClass, String targetFullName) {
+        CoreBaseInfo childObject = null; // 初始化子对象
+
+        if (parentValue instanceof IObjectCollection) { // 检查父属性值是否为对象集合
+            IObjectCollection collection = (IObjectCollection) parentValue; // 转换父属性值
+            if (collection.size() == 0) { // 检查集合是否为空
+                childObject = (CoreBaseInfo) MetaDataUtil.newInstance(targetClass, targetFullName); // 创建新实例
+                collection.addObject(childObject); // 添加到集合
+            } else {
+                childObject = (CoreBaseInfo) collection.getObject(0); // 获取第一个对象
+            }
+        } else if (parentValue instanceof CoreBaseInfo) { // 检查父属性值是否为CoreBaseInfo
+            if (parentValue == null) { // 检查是否为空
+                childObject = (CoreBaseInfo) MetaDataUtil.newInstance(targetClass, targetFullName); // 创建新实例
+            } else {
+                childObject = (CoreBaseInfo) parentValue; // 使用现有对象
+            }
+        }
+
+        return childObject; // 返回子对象
+    }
+
+    /**
+     * 主方法,用于本地测试
+     * 可以在此添加测试代码,验证类的功能
+     *
+     * @param args 命令行参数
+     */
+    public static void main(String[] args) {
+        // 测试代码可以在这里添加
+        System.out.println("AssistSynchronizingFacadeControllerBean main method"); // 输出主方法信息
+    }
+}