package com.sundata.internalevaluation.calc.calcUnit; import cn.hutool.extra.spring.SpringUtil; import com.sundata.common.util.JsonUtil; import com.sundata.internalevaluation.calc.model.CalcResult; import com.sundata.internalevaluation.calc.model.CalcUnit; import com.sundata.internalevaluation.calc.model.finals.CalcType; import com.sundata.internalevaluation.conf.JsonToCalciteExample; import com.sundata.internalevaluation.configuration.model.DataSetConfigModel; import com.sundata.internalevaluation.configuration.model.IndexConfigModel; import com.sundata.internalevaluation.configuration.model.IndexSourceModel; import com.sundata.internalevaluation.configuration.service.DataSetConfigService; import com.sundata.internalevaluation.configuration.service.IndexConfigService; import com.sundata.internalevaluation.script.ScriptUtil; import com.sundata.internalevaluation.script.TemplateUtil; import org.apache.calcite.jdbc.CalciteConnection; import org.apache.calcite.schema.SchemaPlus; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; public class IndexCalcUnit extends CalcUnit { private final IndexConfigModel indexConfigModel; private static final Logger log = LoggerFactory.getLogger(IndexCalcUnit.class); // 接收表集 private Set tableSet = null; /** * 创建数据单元的绝对对象,对象必须包含如下参数 * * @param calcCode 计算对象编号 * @param calcName 计算对象名称 * @param initContext 计算单元初始化参数 */ public IndexCalcUnit(String calcCode, String calcName, Map initContext, IndexConfigModel indexConfigModel) { super(calcCode, calcName, CalcType.INDEX, initContext); this.indexConfigModel = indexConfigModel; } /** * 判断是否已经计算过数据了 * * @param calculateInstanceNumber 计算流水号 * @return 是否计算过 true 计算过 false 没有计算过 */ @Override public boolean isCalcFinished(String calculateInstanceNumber) { // TODO 计算是否已经计算 return false; // return DataImages.indexCalcUnitHashMap.containsKey(calculateInstanceNumber) && DataImages.indexCalcUnitHashMap.get(calculateInstanceNumber).stream().anyMatch(a -> a.getCalcCode().equals(this.getCalcCode())); } /** * 初始化计算结果的方法,如果已经计算过,在实现过程中,应当在此方法中根据计算流水号重新初始化 resultContext 结果对象,为其他依赖对象做准备 * 若明明计算过本单元但再次计算时没有初始化该对象,则计算依赖出现问题无法定位与处理 * * @param calculateInstanceNumber 计算流水号 */ @Override public void initResultContext(String calculateInstanceNumber) { // TODO 初始化 // List indexCalcUnits = new ArrayList<>(); //// List indexCalcUnits = DataImages.indexCalcUnitHashMap.get(calculateInstanceNumber); // // 筛选并查找对象,如果找不到则报错 // if (indexCalcUnits.stream().noneMatch(a -> a.getCalcCode().equals(this.getCalcCode()))) { // throw new CalcException(calculateInstanceNumber, StrUtil.format("无法找到已计算完成的结果,计算单元编号:{},计算流水号为:{}。", this.getCalcCode(), calculateInstanceNumber)); // } // this.setResultContext(indexCalcUnits.stream().filter(a -> a.getCalcCode().equals(this.getCalcCode())).findFirst().get().getResultContext()); } /** * 根据节点配置获取源节点; * * @return 所有源头节点 */ @Override public List getSourceCalcUnits() { // TODO 获取源头节点 DataSetConfigService dataSetService = SpringUtil.getBean(DataSetConfigService.class); IndexConfigService indexConfigService = SpringUtil.getBean(IndexConfigService.class); List selectList = indexConfigService.getIndexSourceList(this.indexConfigModel); // 定义存放数据集和其他指标的集合 List indexList = new ArrayList<>(); List dataSetList = new ArrayList<>(); // 查询个指标编号和数据集对应的数据 for ( IndexSourceModel m : selectList) { if ("DATASET".equals(m.getDataSourceType())) { DataSetConfigModel conditionModel = new DataSetConfigModel(); conditionModel.setDataSetNo(m.getDataSetNo()); DataSetConfigModel datasetModel = dataSetService.selectDetailData(conditionModel); dataSetList.add(datasetModel); } else if ("INDEX".equals(m.getDataSourceType())) { IndexConfigModel conditionModel = new IndexConfigModel(); conditionModel.setIndexNo(m.getOtherIndexNo()); IndexConfigModel indexConfigModel = indexConfigService.selectDetailData(conditionModel); indexList.add(indexConfigModel); } } List indexCalcList = null; List dataSetCalcList = null; List resultCalcMap = new ArrayList<>(); // 数据源头节点生成 if (!indexList.isEmpty()) { indexCalcList = indexList.stream().map(indexConfigModel -> new IndexCalcUnit (indexConfigModel.getIndexNo(),indexConfigModel.getIndexName(),Map.of(),indexConfigModel)).collect(Collectors.toList()); } if (!dataSetList.isEmpty()) { dataSetCalcList = dataSetList.stream().map(dataSetModel -> new DataSetCalcUnit (dataSetModel.getDataSetNo(),dataSetModel.getDataSetName(),Map.of(),dataSetModel)).collect(Collectors.toList()); } // selectList.stream().map(sourceModel -> new IndexSourceCalcUnit // (sourceModel.getOtherIndexNo(),"",CalcType.INDEX,Map.of(),sourceModel)); // 结果封装 if (null != indexCalcList) { resultCalcMap.addAll(indexCalcList); } if (null != dataSetCalcList) { resultCalcMap.addAll(dataSetCalcList); } return resultCalcMap; // return ConfigImages.indexCalcUnitListMap.get(this); } /** * 计算之后的方法,可实现为空 * * @param context 计算参数过程数据 */ @Override public void afterCalc(Map context) { log.debug("计算之后的参数结构:{}",context); } /** * 计算之前,可实现空 * * @param context 计算参数过程数据 */ @Override public void beforeCalc(Map context) { log.debug("计算之前的参数结构:{}",context); } /** * 必须实现的主体计算内容 * * @param context 节点计算参数清单 * @param sourceResults 整个计算过程中的节点结果 */ @Override public void calc(final CalcResult thisResult, String calculateInstanceNumber, Map context, Map> sourceResults) { // TODO 实际的计算过程 // 记录数据集出现次数 AtomicInteger dataSetNumber = new AtomicInteger(); // 记录其他指标出现次数 AtomicInteger indexNumber = new AtomicInteger(); // 声明只存放指标源头节点变量 Map indexResult = new HashMap<>(); // 声明只存放所有数据集源头节点变量 Map dataSetResult = new HashMap<>(); sourceResults.forEach((calcUnit,result) -> { // 数据集 if ( calcUnit instanceof DataSetCalcUnit dataSetCalcUnit){ if(dataSetCalcUnit.getCalcType() == CalcType.DATASET){ dataSetNumber.getAndIncrement(); dataSetResult.putAll((Map) result.get(calcUnit.getCalcCode())); } } // 其他指标 if( calcUnit instanceof IndexCalcUnit indexCalcUnit){ if(indexCalcUnit.getCalcType() == CalcType.INDEX){ indexNumber.getAndIncrement(); indexResult.putAll(result); } } }); // TODO // TODO if (dataSetNumber.get() > 0 && indexNumber.get() == 0){ String json = JsonUtil.toJSONString(dataSetResult); JsonToCalciteExample jsonUtil = new JsonToCalciteExample(); // 如果数据集的数量大于0 // 获取指标逻辑 String logic = indexConfigModel.getIndexLogic(); Object resValue = jsonUtil.jsonTotable(this.getCalcCode(),json,logic); // 执行sql,并放进结果集内 // TODO 计算逻辑 thisResult.put(this.getCalcCode(),resValue); } if(indexNumber.get() > 0 && dataSetNumber.get() == 0){ // 如果指标的数量大于0 // 获取指标逻辑 String logic = indexConfigModel.getIndexLogic(); // 执行公式,结果放入结果集 Object result = ScriptUtil.executeScript(indexConfigModel.getIndexNo(),logic,indexResult); // JsonToCalciteExample.jsonTotable() thisResult.put(this.getCalcCode(),result); } if (dataSetNumber.get() > 0 && indexNumber.get() >0) { // 同时具有指标和数据集 JsonToCalciteExample jsonUtil = new JsonToCalciteExample(); // 获取指标逻辑 String logic = indexConfigModel.getIndexLogic(); // 先将sql中指标公式替换掉,再将得到的sql执行 String editSql = TemplateUtil.execute(indexConfigModel.getIndexNo(),logic,indexResult); // 将数据集得到的数据转json String json = JsonUtil.toJSONString(dataSetResult); // 执行拿结果 Object resValue = jsonUtil.jsonTotable(this.indexConfigModel.getIndexNo(),json,editSql); // 放结果 thisResult.put(this.getCalcCode(),resValue); } } /** * * @param calciteConnection * @param sql * @return */ public Object getConnectionTable (CalciteConnection calciteConnection,String sql) { //获取域 SchemaPlus rootSchemafter = calciteConnection.getRootSchema(); //根域中获取子域 SchemaPlus childrenSchema=rootSchemafter.getSubSchema(this.getCalcCode()); //子域名 String childrenName = childrenSchema.getName(); System.out.println("childrenName: " + childrenName); //子域中表名 tableSet = childrenSchema.getTableNames(); String value = ""; try { Statement statement = calciteConnection.createStatement(); ResultSet resultSet = statement.executeQuery(sql); if (resultSet.next()){ //value = resultSet.getString(1); return resultSet.getObject(1); // System.out.println(); } } catch (SQLException e) { throw new RuntimeException(e); } return null; } }