package com.sundata.internalevaluation.calc.calcUnit; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.spring.SpringUtil; import com.sundata.common.util.DBExecutor; import com.sundata.internalevaluation.calc.model.CalcException; 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.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.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; public class IndexCalcUnit extends CalcUnit { private IndexConfigModel indexConfigModel; private static final Logger log = LoggerFactory.getLogger(IndexCalcUnit.class); /** * 创建数据单元的绝对对象,对象必须包含如下参数 * * @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 (m.getDataSourceType().equals("DATASET")) { DataSetConfigModel datasetModel = dataSetService.selectDetailData(new DataSetConfigModel()); dataSetList.add(datasetModel); } else if (m.getDataSourceType().equals("INDEX")) { IndexConfigModel indexConfigModel = indexConfigService.selectDetailData(new IndexConfigModel()); indexList.add(indexConfigModel); } } List indexCalcList = null; List dataSetCalcList = null; List resultCalcMap = new ArrayList<>(); // 数据源头节点生成 if (indexList.size() > 0) { indexCalcList = indexList.stream().map(indexConfigModel -> new IndexCalcUnit (indexConfigModel.getIndexNo(),indexConfigModel.getIndexName(),Map.of(),indexConfigModel)).collect(Collectors.toList()); } if (dataSetList.size() > 0) { 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)); // 结果封装 resultCalcMap.addAll(indexCalcList); resultCalcMap.addAll(dataSetCalcList); return new ArrayList<>(); // 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(); // 声明只存放指标源头节点变量 AtomicReference> indexResult = new AtomicReference<>(); // 声明只存放所有数据集源头节点变量 AtomicReference> dataSetResult = new AtomicReference<>(); sourceResults.forEach((calcUnit,result) -> { // 数据集 if ( calcUnit instanceof DataSetCalcUnit dataSetCalcUnit){ if(dataSetCalcUnit.getCalcType() == CalcType.DATASET){ dataSetNumber.getAndIncrement(); dataSetResult.setOpaque(result); } } // 其他指标 if( calcUnit instanceof IndexCalcUnit indexCalcUnit){ if(indexCalcUnit.getCalcType() == CalcType.INDEX){ indexNumber.getAndIncrement(); indexResult.setOpaque(result); } } }); if (dataSetNumber.get() > 0 && indexNumber.get() == 0){ // 如果数据集的数量大于0 // 获取指标逻辑 String logic = indexConfigModel.getIndexLogic(); // 执行sql,并放进结果集内 // JsonToCalciteExample.jsonTotable() // TODO 计算逻辑 thisResult.put(this.getCalcCode(),DBExecutor.doQueryMap(logic)); } if(indexNumber.get() > 0 && dataSetNumber.get() == 0){ // 如果指标的数量大于0 // 获取指标逻辑 String logic = indexConfigModel.getIndexLogic(); // 执行公式,结果放入结果集 Object result = ScriptUtil.executeScript(indexConfigModel.getIndexNo(),logic,indexResult.get()); // JsonToCalciteExample.jsonTotable() thisResult.put(this.getCalcCode(),result); } if (dataSetNumber.get() > 0 && indexNumber.get() >0) { // 同时具有指标和数据集 // 获取指标逻辑 String logic = indexConfigModel.getIndexLogic(); // 先将sql作为一个 进行处理,将指标的结果作为参数带入模板成为一个新模板,后在将数据集的参数带入 String editSql = TemplateUtil.execute(indexConfigModel.getIndexNo(),logic,indexResult.get()); // JsonToCalciteExample.jsonTotable() thisResult.put(this.getCalcCode(),DBExecutor.doQueryMap(editSql)); } } }