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 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(); @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) { log.info("SQL ExpressFormula {}, formulaVars {}", expressFormula, formulaVars); RecordSet rs = new RecordSet(); String formulaRunScript = expressFormula.getFormulaRunScript(); String extendParam = expressFormula.getExtendParam(); String sqlReturnKey = ""; try { JsonNode jsonNode = objectMapper.readTree(extendParam); JsonNode sqlReturnKeyNode = jsonNode.get("sqlReturnKey"); if (sqlReturnKeyNode != null) { sqlReturnKey = sqlReturnKeyNode.asText(); } } catch (JsonProcessingException e) { log.error("express execute fail, sql extendParam parse fail", e); } String sql = formulaRunScript; for (FormulaVar formulaVar : formulaVars) { sql = sql.replaceAll(formulaVar.getFieldId(), "'" + formulaVar.getContent() + "'"); } log.info("sql run {}", sql); if (rs.execute(sql)) { if (rs.next()) { return rs.getString(sqlReturnKey); } } return StringUtils.EMPTY; } private Object runFormula(ExpressFormula expressFormula, List formulaVars) throws Exception { 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); } }