|
|
@@ -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"); // 输出主方法信息
|
|
|
+ }
|
|
|
+}
|