package com.engine.salary.service.impl; import com.engine.core.impl.Service; import com.engine.salary.encrypt.AESEncryptUtil; 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.engine.salary.sys.enums.OpenEnum; 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 {}", expressFormula); } //解析配置,获取返回值、数据源 String extendParam = expressFormula.getExtendParam(); String sqlReturnKey = ""; String datasourceId = ""; String openDecrypt = ""; String result = ""; 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(); } } //是否需要解密 JsonNode decrypt = jsonNode.get("openDecrypt"); if (decrypt != null) { openDecrypt = decrypt.asText().trim(); } } 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("ExpressFormula sql run {}", sql); } //外部数据源 if (StringUtils.isNotBlank(datasourceId)) { RecordSetDataSource rs = new RecordSetDataSource(datasourceId); if (rs.executeSql(sql)) { if (rs.next()) { result = rs.getString(sqlReturnKey); } } } else { RecordSet rs = new RecordSet(); if (rs.execute(sql)) { if (rs.next()) { result = rs.getString(sqlReturnKey); } } } if (OpenEnum.OPEN.getValue().equals(openDecrypt)) { result = AESEncryptUtil.decrypt(result); } return result; } private Object runFormula(ExpressFormula expressFormula, List formulaVars) throws Exception { if (isLog) { log.info("FORMULA ExpressFormula {} {}", expressFormula.getFormula(), expressFormula.getFormulaRunScript()); } DefaultContext context = new DefaultContext(); formulaVars.forEach(v -> { if (isLog) { log.info("FORMULA formulaVar {} - {}", v.getFieldId(), v.getContent()); } 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); } }