package com.engine.salary.service.impl; import com.engine.core.impl.Service; import com.engine.salary.entity.datacollection.DataCollectionEmployee; import com.engine.salary.entity.salaryformula.ExpressFormula; import com.engine.salary.entity.salaryformula.po.FormulaVar; import com.engine.salary.enums.salaryformula.ReferenceTypeEnum; import com.engine.salary.formlua.entity.parameter.DataType; import com.engine.salary.service.FormulaRunService; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.ql.util.express.DefaultContext; import com.ql.util.express.ExpressRunner; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import weaver.conn.RecordSet; import weaver.conn.RecordSetDataSource; import weaver.general.BaseBean; import java.math.BigDecimal; import java.util.List; @Slf4j public class FormulaRunServiceImpl extends Service implements FormulaRunService { private static ExpressRunner runner = new ExpressRunner(true, false); private static final ObjectMapper objectMapper = new ObjectMapper(); private final BaseBean baseBean = new BaseBean(); private final Boolean isLog = "true".equals(baseBean.getPropValue("hrmSalary", "log")); @Override public Object run(ExpressFormula expressFormula, List formulaVars, DataCollectionEmployee simpleEmployee) throws Exception { if (ReferenceTypeEnum.parseByValue(expressFormula.getReferenceType()) == ReferenceTypeEnum.FORMULA) { return runFormula(expressFormula, formulaVars); } if (ReferenceTypeEnum.parseByValue(expressFormula.getReferenceType()) == ReferenceTypeEnum.SQL) { return runSQL(expressFormula, formulaVars); } log.error("express execute fail, {} not in ReferenceTypeEnum ", expressFormula.getReferenceType()); return StringUtils.EMPTY; } private String runSQL(ExpressFormula expressFormula, List formulaVars) { if (isLog) { log.info("SQL ExpressFormula {}, formulaVars {}", expressFormula, formulaVars); } //解析配置,获取返回值、数据源 String extendParam = expressFormula.getExtendParam(); String sqlReturnKey = ""; String datasourceId = ""; try { JsonNode jsonNode = objectMapper.readTree(extendParam); //返回值配置 JsonNode sqlReturnKeyNode = jsonNode.get("sqlReturnKey"); if (sqlReturnKeyNode != null) { sqlReturnKey = sqlReturnKeyNode.asText().trim(); } //数据源配置 JsonNode datasourceNode = jsonNode.get("datasource"); if (datasourceNode != null) { JsonNode datasourceIdNode = datasourceNode.get("datasourceId"); if (datasourceIdNode != null) { datasourceId = datasourceIdNode.asText(); } } } catch (JsonProcessingException e) { log.error("express execute fail, sql extendParam parse fail", e); } //解析sql String sql = expressFormula.getFormulaRunScript(); for (FormulaVar formulaVar : formulaVars) { sql = sql.replaceAll(formulaVar.getFieldId(), "'" + formulaVar.getContent() + "'"); } if (isLog) { log.info("sql run {}", sql); } //外部数据源 if (StringUtils.isNotBlank(datasourceId)) { RecordSetDataSource rs = new RecordSetDataSource(datasourceId); if (rs.executeSql(sql)) { if (rs.next()) { return rs.getString(sqlReturnKey); } } } else { RecordSet rs = new RecordSet(); if (rs.execute(sql)) { if (rs.next()) { return rs.getString(sqlReturnKey); } } } return StringUtils.EMPTY; } private Object runFormula(ExpressFormula expressFormula, List formulaVars) throws Exception { if (isLog) { log.info("FORMULA ExpressFormula {}, formulaVars {}", expressFormula, formulaVars); } DefaultContext context = new DefaultContext(); formulaVars.forEach(v -> { if (DataType.NUMBER.equals(v.getFieldType()) && NumberUtils.isCreatable(v.getContent())) { context.put(v.getFieldId(), new BigDecimal(v.getContent())); } else { context.put(v.getFieldId(), v.getContent()); } }); String formula = expressFormula.getFormulaRunScript(); return runner.execute(formula, context, null, true, false); } }