Quellcode durchsuchen

添加对树以及相关配置的支持。完善总账勾稽的计算过程。

CodeLife Leno vor 1 Monat
Ursprung
Commit
a26857c4de

+ 12 - 0
Procedure/backend/project/src/main/java/com/sundata/product/rwa/calc/service/implement/extend/UpperMapRowMapper.java

@@ -0,0 +1,12 @@
+package com.sundata.product.rwa.calc.service.implement.extend;
+
+import org.springframework.jdbc.core.ColumnMapRowMapper;
+
+public class UpperMapRowMapper extends ColumnMapRowMapper {
+
+    @Override
+    protected String getColumnKey(String columnName) {
+        // 自定义列名处理
+        return columnName.toUpperCase();
+    }
+}

+ 135 - 7
Procedure/backend/project/src/main/java/com/sundata/product/rwa/calc/service/implement/units/GeneralLedgerUnit.java

@@ -1,7 +1,5 @@
 package com.sundata.product.rwa.calc.service.implement.units;
 
-import cn.hutool.core.convert.NumberChineseFormatter;
-import cn.hutool.core.convert.NumberWordFormatter;
 import cn.hutool.core.util.NumberUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.extra.spring.SpringUtil;
@@ -9,18 +7,24 @@ import com.sundata.common.util.DBExecutor;
 import com.sundata.product.rwa.calc.service.CalcResult;
 import com.sundata.product.rwa.calc.service.CalcUnit;
 import com.sundata.product.rwa.calc.service.finals.CalcType;
+import com.sundata.product.rwa.calc.service.implement.extend.UpperMapRowMapper;
 import com.sundata.product.rwa.calc.utils.FinalStrs;
 import com.sundata.product.rwa.calc.utils.UnitStaticFun;
 import com.sundata.product.rwa.resultList.model.DiffconfigListModel;
 import com.sundata.product.rwa.resultList.model.RuleListModel;
 import com.sundata.product.rwa.resultList.service.DiffconfigListService;
 import com.sundata.product.rwa.resultList.service.RuleListService;
+import com.sundata.product.rwa.rwaCalcConfig002offbalanceprotype.model.InfoListModel;
+import com.sundata.product.rwa.rwacalcconfig001riskexposure.model.RiskExposureDefinitionModel;
+import com.sundata.product.rwa.util.DataUtil;
 import org.apache.commons.text.StringSubstitutor;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
 
+import javax.sql.DataSource;
 import java.math.BigDecimal;
-import java.math.MathContext;
 import java.math.RoundingMode;
 import java.text.DecimalFormat;
 import java.util.HashMap;
@@ -106,20 +110,71 @@ public class GeneralLedgerUnit extends CalcUnit {
     public void calc(CalcResult<String, Object> thisResult, String calculateInstanceNumber, Map<String, Object> context, Map<CalcUnit, CalcResult<String, Object>> sourceResults) {
         // 计算过程中,需要循环配置表并将每一个数据进行处理
         StringSubstitutor sub = new StringSubstitutor(context);
+        JdbcTemplate jdbcTemplate = SpringUtil.getBean(JdbcTemplate.class);
+        if (jdbcTemplate == null) {
+            jdbcTemplate = new JdbcTemplate(SpringUtil.getBean(DataSource.class));
+        }
+        MapSqlParameterSource sqlParam = new MapSqlParameterSource(context);
+        sqlParam.addValue("ORGCODE", "000000");// TODO 找不到对应科目的法人机构号
+
         RuleListService ruleListService = SpringUtil.getBean(RuleListService.class);
         List<RuleListModel> ruleListModels = ruleListService.rule_list(new RuleListModel());
         DiffconfigListService diffconfigListService = SpringUtil.getBean(DiffconfigListService.class);
         List<DiffconfigListModel> diffconfigListModels = diffconfigListService.rule_querylist(new DiffconfigListModel());
         Map<String, DiffconfigListModel> subjectDiffConfig = new HashMap<>();
 
+        // 初始化 表外项目划分
+        List<Map<String, Object>> offObjectTypes = jdbcTemplate.query("select CALCINDEX, SDATE, EDATE, TERM, DATA_DATE, OFFOBJECT_NO, OFFOBJECT_NAME, OFFOBJECT_STAGE_ID, OFFOBJECT_INDEX, DEFAULT_OUT, OFFOBJECT_SUPER, ISMINI, CCF, RISK_EXPOSE_CLASS_CODE, YESORNO from RWA_CALC_CONF_OFFBALANCEPROTYPE", new UpperMapRowMapper());
+        Map<String, InfoListModel> infoListModel = new HashMap<>();
+        for (Map<String, Object> offObjectType : offObjectTypes) {
+            InfoListModel model = new InfoListModel();
+            model.setCalcindex((String) DataUtil.getDataDefault(offObjectType.get("CALCINDEX"), String.class));
+            model.setSdate((String) DataUtil.getDataDefault(offObjectType.get("SDATE"), String.class));
+            model.setEdate((String) DataUtil.getDataDefault(offObjectType.get("EDATE"), String.class));
+            model.setTerm((String) DataUtil.getDataDefault(offObjectType.get("TERM"), String.class));
+            model.setDataDate((String) DataUtil.getDataDefault(offObjectType.get("DATA_DATE"), String.class));
+            model.setOffobjectNo((String) DataUtil.getDataDefault(offObjectType.get("OFFOBJECT_NO"), String.class));
+            model.setOffobjectName((String) DataUtil.getDataDefault(offObjectType.get("OFFOBJECT_NAME"), String.class));
+            model.setOffobjectStageId((String) DataUtil.getDataDefault(offObjectType.get("OFFOBJECT_STAGE_ID"), String.class));
+            model.setOffobjectIndex((BigDecimal) DataUtil.getDataDefault(offObjectType.get("OFFOBJECT_INDEX"), BigDecimal.class));
+            model.setDefaultOut((String) DataUtil.getDataDefault(offObjectType.get("DEFAULT_OUT"), String.class));
+            model.setOffobjectSuper((String) DataUtil.getDataDefault(offObjectType.get("OFFOBJECT_SUPER"), String.class));
+            model.setIsmini((String) DataUtil.getDataDefault(offObjectType.get("ISMINI"), String.class));
+            model.setCcf((BigDecimal) DataUtil.getDataDefault(offObjectType.get("CCF"), BigDecimal.class));
+            model.setRiskExposeClassCode((String) DataUtil.getDataDefault(offObjectType.get("RISK_EXPOSE_CLASS_CODE"), String.class));
+            model.setYesorno((String) DataUtil.getDataDefault(offObjectType.get("YESORNO"), String.class));
+            infoListModel.put(model.getOffobjectNo(), model);
+        }
+        // 初始化 风险暴露分类
+        List<Map<String, Object>> riskTypeList = jdbcTemplate.query("select CALCINDEX, SDATE, EDATE, TERM, DATA_DATE, RISKEXPOSURE_NO, RISKEXPOSURE_NAME,RISKEXPOSURE_STAGE_ID, DEFAULT_OUT, RISKEXPOSURE_INDEX, RISKEXPOSURE_SUPER,RISKEXPOSURE_ISMINI, RISKEXPOSURE_WEIGHT, RISKEXPOSURE_STATE from RWA_CALC_CONF_RISKEXPOSURE", new UpperMapRowMapper());
+        Map<String, RiskExposureDefinitionModel> riskExposureDefinitionModelMap = new HashMap<>();
+        for (Map<String, Object> riskType : riskTypeList) {
+            RiskExposureDefinitionModel model = new RiskExposureDefinitionModel();
+            model.setCalcIndex((String) DataUtil.getDataDefault(riskType.get("CALCINDEX"), String.class));
+            model.setStartDate((String) DataUtil.getDataDefault(riskType.get("SDATE"), String.class));
+            model.setEndDate((String) DataUtil.getDataDefault(riskType.get("EDATE"), String.class));
+            model.setTerm((String) DataUtil.getDataDefault(riskType.get("TERM"), String.class));
+            model.setDataDate((String) DataUtil.getDataDefault(riskType.get("DATA_DATE"), String.class));
+            model.setRiskExposureNo((String) DataUtil.getDataDefault(riskType.get("RISKEXPOSURE_NO"), String.class));
+            model.setRiskExposureName((String) DataUtil.getDataDefault(riskType.get("RISKEXPOSURE_NAME"), String.class));
+            model.setRiskExposureStageId((String) DataUtil.getDataDefault(riskType.get("RISKEXPOSURE_STAGE_ID"), String.class));
+            model.setDefaultOut((String) DataUtil.getDataDefault(riskType.get("DEFAULT_OUT"), String.class));
+            model.setRiskExposureIndex((String) DataUtil.getDataDefault(riskType.get("RISKEXPOSURE_INDEX"), String.class));
+            model.setRiskExposureSuper((String) DataUtil.getDataDefault(riskType.get("RISKEXPOSURE_SUPER"), String.class));
+            model.setRiskExposureIsmini((String) DataUtil.getDataDefault(riskType.get("RISKEXPOSURE_ISMINI"), String.class));
+            model.setRiskExposureWeight((BigDecimal) DataUtil.getDataDefault(riskType.get("RISKEXPOSURE_WEIGHT"), BigDecimal.class));
+            model.setRiskExposureState((String) DataUtil.getDataDefault(riskType.get("RISKEXPOSURE_STATE"), String.class));
+            riskExposureDefinitionModelMap.put(model.getRiskExposureNo(), model);
+        }
+
+
         for (DiffconfigListModel diffconfigListModel : diffconfigListModels) {
             List<RuleListModel> ruleListModelList = diffconfigListService.rule_queryone2(diffconfigListModel.getRuleNo());
             for (RuleListModel ruleListModel : ruleListModelList) {
                 subjectDiffConfig.put(ruleListModel.getGlCode(), diffconfigListModel);
             }
         }
-        // TODO 需要获取容忍度处理逻辑,并将容忍度处理逻辑处理为一个基于科目编号的map,下面的处理过程中,根据实际容忍度处理结果
-        // TODO 这两个表不存在 select * from RWA_LEART_INS_LEDGRESULT; select * from RWA_APM_BUS_RS_ACCADJUSTMENT;
+
         for (RuleListModel ruleListModel : ruleListModels) {
 
             String subjectSql = sub.replace(ruleListModel.getSubjectSql());
@@ -160,10 +215,19 @@ public class GeneralLedgerUnit extends CalcUnit {
             }
 
             DiffconfigListModel diffconfigListModel = subjectDiffConfig.get(ruleListModel.getGlCode());
-            boolean isInDiff = true;
 //            BigDecimal differAmt = BigDecimal.ZERO; // 核对差异金额(万元)
             BigDecimal differRate = differAmt.divide(subjectSumBigDecimal, 8, RoundingMode.HALF_UP); // 核对差异率%
+            if (differAmt.compareTo(BigDecimal.ZERO) == 0 && subjectSumBigDecimal.compareTo(BigDecimal.ZERO) == 0) {
+                differRate = BigDecimal.ZERO;
+            }
+            if (differAmt.compareTo(BigDecimal.ZERO) > 0 && subjectSumBigDecimal.compareTo(BigDecimal.ZERO) == 0) {
+                differRate = BigDecimal.valueOf(999.99);
+            }
+            if (differAmt.compareTo(BigDecimal.ZERO) < 0 && subjectSumBigDecimal.compareTo(BigDecimal.ZERO) == 0) {
+                differRate = BigDecimal.valueOf(-999.99);
+            }
             String percThreshold = "[0.0-0.0]"; // 差异容忍度%
+            char isOutDiff = '0';
             if (diffconfigListModel != null) {
 //                close - close
 //                close - open
@@ -181,8 +245,72 @@ public class GeneralLedgerUnit extends CalcUnit {
                 intervalType = StrUtil.replace(intervalType, "[open", "(");
                 String[] split = intervalType.split("-");
                 DecimalFormat df = new DecimalFormat("#,##0.00");
-                percThreshold = split[0] + df.format(diffconfigListModel.getUpperLimit()) + "-" + df.format(diffconfigListModel.getLowerLimit()) + split[1];
+                /*
+                PERCTHRESHOLD 差异容忍度%
+                 */
+                percThreshold = split[0] + " " + df.format(diffconfigListModel.getUpperLimit().doubleValue() * 100) + "% - " + df.format(diffconfigListModel.getLowerLimit().doubleValue() * 100) + "% " + split[1];
+
+                if (differRate.doubleValue() > diffconfigListModel.getLowerLimit().doubleValue() || differRate.doubleValue() < diffconfigListModel.getUpperLimit().doubleValue()) {
+                    // 如果 差异率大于上限或小于下限
+                    // 处理结果插入平账表中
+                    isOutDiff = '1';
+                    String insertAccadjustment = "insert into rwa_apm_bus_rs_accadjustment (CALCINDEX, SDATE, EDATE, TERM, DATA_DATE, GL_CODE, SUBJECT_DESC,LOAN_REFERENCE_NO, BALANCE_ON, BALANCE_OFF, RESERVE, CURRENCY,RISK_EXPOSURE_LEV01_CODE, RISK_EXPOSURE_LEV01_CODE_NAME,RISK_EXPOSURE_LEV02_CODE, RISK_EXPOSURE_LEV02_CODE_NAME,RISK_EXPOSURE_LEV03_CODE, RISK_EXPOSURE_LEV03_CODE_NAME,RISK_EXPOSURE_LEV04_CODE, RISK_EXPOSURE_LEV04_CODE_NAME, RISK_RESULT,LOAN_WEIGHT, COVERAGE_RISK, COVERAGE_RWA, UNFINISH_EAD, UNFINISH_RWA, RWA,CUST_NAME, CUST_NO, BP_CUST_NO, INVEST_INDUSTRY, BUSINESS_LINE, EFF_DATE,DUE_DATE, SOFT_RULE_TYPE, SOFT_RULE_MAINID, SOFT_RULE_SUBID) " +
+                            "values (:CALCINDEX, :SDATE, :EDATE, :TERM, :DATA_DATE, :GL_CODE, :SUBJECT_DESC, :LOAN_REFERENCE_NO, :BALANCE_ON,:BALANCE_OFF, :RESERVE, :CURRENCY, :RISK_EXPOSURE_LEV01_CODE, :RISK_EXPOSURE_LEV01_CODE_NAME,:RISK_EXPOSURE_LEV02_CODE, :RISK_EXPOSURE_LEV02_CODE_NAME, :RISK_EXPOSURE_LEV03_CODE,:RISK_EXPOSURE_LEV03_CODE_NAME, :RISK_EXPOSURE_LEV04_CODE, :RISK_EXPOSURE_LEV04_CODE_NAME, :RISK_RESULT,:LOAN_WEIGHT, :COVERAGE_RISK, :COVERAGE_RWA, :UNFINISH_EAD, :UNFINISH_RWA, :RWA, :CUST_NAME, :CUST_NO,:BP_CUST_NO, :INVEST_INDUSTRY, :BUSINESS_LINE, :EFF_DATE, :DUE_DATE, :SOFT_RULE_TYPE, :SOFT_RULE_MAINID,:SOFT_RULE_SUBID)";
+                    sqlParam.addValue("GL_CODE", ruleListModel.getRuleNo());
+                    sqlParam.addValue("SUBJECT_DESC", subjectSum);
+                    sqlParam.addValue("LOAN_REFERENCE_NO", "XNZX" + ruleListModel.getRuleNo());
+                    sqlParam.addValue("BALANCE_ON", productSum);
+                    sqlParam.addValue("BALANCE_OFF", isOutDiff);
+                    sqlParam.addValue("RESERVE", percThreshold);
+                    sqlParam.addValue("CURRENCY", "CNY");
+                    sqlParam.addValue("RISK_EXPOSURE_LEV01_CODE", "");
+                    sqlParam.addValue("RISK_EXPOSURE_LEV01_CODE_NAME", "");
+                    sqlParam.addValue("RISK_EXPOSURE_LEV02_CODE", "");
+                    sqlParam.addValue("RISK_EXPOSURE_LEV02_CODE_NAME", "");
+                    sqlParam.addValue("RISK_EXPOSURE_LEV03_CODE", "");
+                    sqlParam.addValue("RISK_EXPOSURE_LEV03_CODE_NAME", "");
+                    sqlParam.addValue("RISK_EXPOSURE_LEV04_CODE", "");
+                    sqlParam.addValue("RISK_EXPOSURE_LEV04_CODE_NAME", "");
+                    sqlParam.addValue("RISK_RESULT", "");
+                    sqlParam.addValue("LOAN_WEIGHT", "");
+                    sqlParam.addValue("COVERAGE_RISK", "");
+                    sqlParam.addValue("COVERAGE_RWA", "");
+                    sqlParam.addValue("UNFINISH_EAD", "");
+                    sqlParam.addValue("UNFINISH_RWA", "");
+                    sqlParam.addValue("RWA", "");
+                    sqlParam.addValue("CUST_NAME", "");
+                    sqlParam.addValue("CUST_NO", "");
+                    sqlParam.addValue("BP_CUST_NO", "");
+                    sqlParam.addValue("INVEST_INDUSTRY", "");
+                    sqlParam.addValue("BUSINESS_LINE", "");
+                    sqlParam.addValue("EFF_DATE", "");
+                    sqlParam.addValue("SOFT_RULE_TYPE", "ACCOUNT");
+                    sqlParam.addValue("SOFT_RULE_MAINID", ruleListModel.getRuleId());
+                    sqlParam.addValue("SOFT_RULE_SUBID", "");
+
+
+                    jdbcTemplate.update(insertAccadjustment, sqlParam);
+                }
             }
+
+
+            sqlParam.addValue("RULE_ID", ruleListModel.getRuleNo());
+            sqlParam.addValue("RULE_NAME", ruleListModel.getRuleName());
+            sqlParam.addValue("SUBJCODE", ruleListModel.getGlCode());
+            sqlParam.addValue("SUBJNAME", ruleListModel.getSubjectDesc());
+            sqlParam.addValue("CCY", "CNY");
+            sqlParam.addValue("GLAMT", subjectSumBigDecimal);
+            sqlParam.addValue("LEDGARTAMT", productSumBigDecimal);
+            sqlParam.addValue("DIFFERAMT", differAmt);
+            sqlParam.addValue("DIFFERRATE", differRate);
+            sqlParam.addValue("PERCTHRESHOLD", percThreshold);
+            sqlParam.addValue("LEARTRESULTTYPE", isOutDiff);
+            sqlParam.addValue("OFFSETDIFFERAMT", differRate);
+            String insertLedgresult = "insert into rwa_leart_ins_ledgresult (CALCINDEX, SDATE, EDATE, TERM, DATA_DATE, ORGCODE, RULE_ID, RULE_NAME, SUBJCODE, SUBJNAME, CCY, GLAMT, LEDGARTAMT" +
+                    ", DIFFERAMT, DIFFERRATE, PERCTHRESHOLD, LEARTRESULTTYPE, OFFSETDIFFERAMT) " +
+                    "values (:CALCINDEX, :SDATE, :EDATE, :TERM, :DATA_DATE, :ORGCODE, :RULE_ID, :RULE_NAME, :SUBJCODE, :SUBJNAME, :CCY, :GLAMT, :LEDGARTAMT, :DIFFERAMT, :DIFFERRATE, :PERCTHRESHOLD, :LEARTRESULTTYPE, :OFFSETDIFFERAMT)";
+            jdbcTemplate.update(insertLedgresult, sqlParam);
+
         }
     }
 }

+ 8 - 6
Procedure/backend/project/src/main/java/com/sundata/product/rwa/resultList/model/DiffconfigListModel.java

@@ -1,5 +1,7 @@
 package com.sundata.product.rwa.resultList.model;
 
+import java.math.BigDecimal;
+
 public class DiffconfigListModel {
     private String  calcindex;   //计算实例号
     private String  sdate;   //起始数据日期
@@ -8,8 +10,8 @@ public class DiffconfigListModel {
     private String  dataDate;   //数据日期
     private String  ruleNo;   //规则编号
     private String  ruleName;   //规则名称
-    private double  upperLimit;   //容忍度下限%
-    private double  lowerLimit;   //容忍度上限%
+    private BigDecimal upperLimit;   //容忍度下限%
+    private BigDecimal lowerLimit;   //容忍度上限%
     private String  intervalType;   //区间开闭类型
     private String  ruleAreaType;   //适用范围类型
 
@@ -69,19 +71,19 @@ public class DiffconfigListModel {
         this.ruleName = ruleName;
     }
 
-    public double getUpperLimit() {
+    public BigDecimal getUpperLimit() {
         return upperLimit;
     }
 
-    public void setUpperLimit(double upperLimit) {
+    public void setUpperLimit(BigDecimal upperLimit) {
         this.upperLimit = upperLimit;
     }
 
-    public double getLowerLimit() {
+    public BigDecimal getLowerLimit() {
         return lowerLimit;
     }
 
-    public void setLowerLimit(double lowerLimit) {
+    public void setLowerLimit(BigDecimal lowerLimit) {
         this.lowerLimit = lowerLimit;
     }
 

+ 9 - 0
Procedure/backend/project/src/main/java/com/sundata/product/rwa/rwaCalcConfig002offbalanceprotype/model/InfoListModel.java

@@ -22,6 +22,7 @@ public class InfoListModel extends BaseModel {
     private String  ismini;   //是否最细一级
     private BigDecimal  ccf;   //转换系数(%)
     private  String offobjectSuperName;  //上级目录名称
+    private String riskExposeClassCode;
     private String yesorno;  //状态
 
     public String getYesorno() {
@@ -153,4 +154,12 @@ public class InfoListModel extends BaseModel {
     public void setCcf(BigDecimal ccf) {
         this.ccf = ccf;
     }
+
+    public String getRiskExposeClassCode() {
+        return riskExposeClassCode;
+    }
+
+    public void setRiskExposeClassCode(String riskExposeClassCode) {
+        this.riskExposeClassCode = riskExposeClassCode;
+    }
 }

+ 8 - 3
Procedure/backend/project/src/main/java/com/sundata/product/rwa/rwacalcconfig001riskexposure/model/RiskExposureDefinitionModel.java

@@ -1,7 +1,12 @@
 package com.sundata.product.rwa.rwacalcconfig001riskexposure.model;
 
+import java.math.BigDecimal;
+
 public class RiskExposureDefinitionModel {
     // 计算实例号
+    /**
+     * 计算实例号
+     */
     private String calcIndex;
     // 起始数据日期
     private String startDate;
@@ -28,7 +33,7 @@ public class RiskExposureDefinitionModel {
     // 是否最细一级
     private String riskExposureIsmini;
     // 默认权重(%)
-    private String riskExposureWeight;
+    private BigDecimal riskExposureWeight;
     // 状态
     private String riskExposureState;
 
@@ -136,11 +141,11 @@ public class RiskExposureDefinitionModel {
         this.riskExposureIsmini = riskExposureIsmini;
     }
 
-    public String getRiskExposureWeight() {
+    public BigDecimal getRiskExposureWeight() {
         return riskExposureWeight;
     }
 
-    public void setRiskExposureWeight(String riskExposureWeight) {
+    public void setRiskExposureWeight(BigDecimal riskExposureWeight) {
         this.riskExposureWeight = riskExposureWeight;
     }
 

+ 68 - 0
Procedure/backend/project/src/main/java/com/sundata/product/rwa/util/DataUtil.java

@@ -0,0 +1,68 @@
+package com.sundata.product.rwa.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigDecimal;
+import java.util.Map;
+import java.util.function.Supplier;
+
+public class DataUtil {
+
+    private static final Logger log = LoggerFactory.getLogger(DataUtil.class);
+
+    public static <T> Object getDataDefault(Object object, Class<T> clazz) {
+        if (object == null) {
+            return getDefaultValue(clazz);
+        } else {
+            // 如果对象的类型与目标类型一致,直接返回
+            if (clazz.isInstance(object)) {
+                return object;
+            } else {
+                // 如果类型不一致,也返回默认值
+                return getDefaultValue(clazz);
+            }
+        }
+    }
+
+    private static <T> Object getDefaultValue(Class<T> clazz) {
+        Map<Class<?>, Supplier<?>> defaultValues = Map.of(
+            String.class, () -> "",
+            Integer.class, () -> 0,
+            Double.class, () -> 0.0,
+            Float.class, () -> 0.0F,
+            Boolean.class, () -> false,
+            java.sql.Date.class, () -> new java.sql.Date(System.currentTimeMillis()),
+            java.util.Date.class, () -> new java.util.Date(System.currentTimeMillis()),
+            Long.class, () -> 0L,
+            BigDecimal.class, () -> BigDecimal.ZERO
+        );
+
+        Supplier<?> defaultValueSupplier = defaultValues.get(clazz);
+        if (defaultValueSupplier != null) {
+            return defaultValueSupplier.get();
+        } else {
+            // 如果没有找到默认值的类型,尝试通过反射创建实例
+            try {
+                return clazz.getDeclaredConstructor().newInstance();
+            } catch (Exception e) {
+                throw new RuntimeException("Failed to create instance for class: " + clazz.getName(), e);
+            }
+        }
+    }
+
+    // 示例使用
+    public static void main(String[] args) {
+        // 示例1:传入null,返回默认值
+        System.out.println(getDataDefault(null, String.class)); // ""
+        System.out.println(getDataDefault(null, Integer.class)); // 0
+
+        // 示例2:传入非null对象,类型匹配
+        System.out.println(getDataDefault(123, Integer.class)); // 123
+        System.out.println(getDataDefault("Hello", String.class)); // "Hello"
+
+        // 示例3:传入非null对象,类型不匹配
+        System.out.println(getDataDefault(123, String.class)); // ""
+        System.out.println(getDataDefault("Hello", Integer.class)); // 0
+    }
+}

+ 106 - 0
Procedure/backend/project/src/main/java/com/sundata/product/rwa/util/TreeData.java

@@ -0,0 +1,106 @@
+package com.sundata.product.rwa.util;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+/**
+ * 树状结构对象逻关系结构对象
+ *
+ * @param <T> 任意数据类型
+ */
+public class TreeData<T> {
+    /**
+     * 组合式对象,表名对象内容
+     */
+    private final T object;
+    /**
+     * 上级对象
+     */
+    private T parent;
+    /**
+     * 获取子对象的方法
+     */
+    private final Function<T, List<T>> getChildrenFunction;
+    /**
+     * 获取父对象的方法
+     */
+    private final Function<T, T> getParentFunction;
+    /**
+     * 子对象的全部Map(所有子对象,key为第一层子集
+     */
+    private final Map<T, List<T>> childrenMap;
+    /**
+     * 级别,如果级别为0,则驱动全部检索过程,处理整个输
+     */
+    private int level;
+    /**
+     * 子对象清单(一级
+     */
+    private List<T> children;
+
+    public TreeData(T object, int level, Function<T, List<T>> getChildrenFunction, Function<T, T> getParentFunction) {
+        this.object = object;
+        this.level = level;
+        this.childrenMap = new LinkedHashMap<>();
+        this.getChildrenFunction = getChildrenFunction;
+        this.getParentFunction = getParentFunction;
+    }
+
+
+    public Function<T, List<T>> getGetChildrenFunction() {
+        return getChildrenFunction;
+    }
+
+    public int getLevel() {
+        return level;
+    }
+
+    public void setLevel(int level) {
+        this.level = level;
+    }
+
+    public T getObject() {
+        if (getParentFunction == null) {
+            return null;
+        }
+        if (parent == null) {
+            parent = getParentFunction.apply(object);
+        }
+        return object;
+    }
+
+    public void initChildren() {
+        if (children == null && getChildrenFunction != null) {
+            children = getChildrenFunction.apply(object);
+            if (level == 0) {
+                for (T child : children) {
+                    TreeData<T> childTreeData = new TreeData<T>(child, level, getChildrenFunction, getParentFunction);
+                    childrenMap.put(child, childTreeData.getChildrenFunction.apply(child));
+                }
+            }
+        }
+    }
+    public List<T> getChildren() {
+        if (children == null || children.isEmpty()) {
+            initChildren();
+        }
+        return children;
+    }
+
+    public Map<T, List<T>> getChildrenMap() {
+        if (childrenMap.isEmpty()) {
+            initChildren();
+        }
+        return childrenMap;
+    }
+
+    public Function<T, T> getGetParentFunction() {
+        return getParentFunction;
+    }
+
+    public T getParent() {
+        return parent;
+    }
+}

+ 25 - 0
Procedure/backend/project/src/main/java/com/sundata/product/rwa/util/TreeDataUtil.java

@@ -0,0 +1,25 @@
+package com.sundata.product.rwa.util;
+
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+public class TreeDataUtil {
+
+
+    public static <V> Map<V, List<V>> getAllTreeDataByRoot(V o, Function<V, List<V>> getSourceFunction) {
+        TreeData<V> treeData = new TreeData<V>(o, 0, getSourceFunction, null);
+        return treeData.getChildrenMap();
+    }
+
+    public static <V> Map<V, List<V>> getChildTreeDataByThis(V o, Function<V, List<V>> getSourceFunction) {
+//        SpringUtil.getBean();
+        Map<V, List<V>> data = new HashMap<>();
+        TreeData<V> treeData = new TreeData<V>(o, 1, getSourceFunction, null);
+        data.put(o, treeData.getChildren());
+        return data;
+    }
+
+}