diff --git a/src/com/engine/salary/service/SalaryFormulaService.java b/src/com/engine/salary/service/SalaryFormulaService.java index 5bc9223f0..55ef4f31c 100644 --- a/src/com/engine/salary/service/SalaryFormulaService.java +++ b/src/com/engine/salary/service/SalaryFormulaService.java @@ -35,8 +35,8 @@ public interface SalaryFormulaService { FormulaPO save(SalaryFormulaSaveParam salaryFormulaSaveParam); - FormulaPO update(SalaryFormulaSaveParam salaryFormulaSaveParam); + Object mock(SalaryFormulaSaveParam param); /** * 初始化函数 diff --git a/src/com/engine/salary/service/impl/SalaryFormulaServiceImpl.java b/src/com/engine/salary/service/impl/SalaryFormulaServiceImpl.java index a012a2f4d..0e7ce6deb 100644 --- a/src/com/engine/salary/service/impl/SalaryFormulaServiceImpl.java +++ b/src/com/engine/salary/service/impl/SalaryFormulaServiceImpl.java @@ -16,7 +16,6 @@ import com.engine.salary.mapper.formula.FormulaVarMapper; import com.engine.salary.service.FormulaRunService; import com.engine.salary.service.SalaryFormulaService; import com.engine.salary.util.db.MapperProxyFactory; -import com.engine.salary.util.valid.RuntimeTypeEnum; import com.engine.salary.util.valid.ValidUtil; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; @@ -112,7 +111,7 @@ public class SalaryFormulaServiceImpl extends Service implements SalaryFormulaSe if (ValidateTypeEnum.parseByValue(param.getValidateType()) == null) { throw new SalaryRunTimeException("校验类型异常"); } - //todo 公式参数与公式内容是否相符 + List parameters = param.getParameters(); //防止参数名和字段名呈现一对多的问题 if (CollectionUtils.isNotEmpty(parameters)) { @@ -259,42 +258,100 @@ public class SalaryFormulaServiceImpl extends Service implements SalaryFormulaSe @Override - public FormulaPO update(SalaryFormulaSaveParam param) { + public Object mock(SalaryFormulaSaveParam param) { - ValidUtil.doValidator(param, RuntimeTypeEnum.UPDATE); - - Long id = param.getId(); - FormulaPO formulaPO = getFormulaMapper().getById(id); - if (formulaPO == null) { - throw new SalaryRunTimeException("公式不存在或已删除"); + ValidUtil.doValidator(param); + if (ReferenceTypeEnum.parseByValue(param.getReferenceType()) == null) { + throw new SalaryRunTimeException("引用类型异常"); + } + if (ReturnTypeEnum.parseByValue(param.getReturnType()) == null) { + throw new SalaryRunTimeException("返回类型异常"); + } + if (ValidateTypeEnum.parseByValue(param.getValidateType()) == null) { + throw new SalaryRunTimeException("校验类型异常"); } - formulaPO.setName(param.getName()); - formulaPO.setDescription(param.getDescription()); - formulaPO.setModule(param.getModule()); - formulaPO.setUseFor(param.getUseFor()); - formulaPO.setReferenceType(param.getReferenceType()); - formulaPO.setReturnType(param.getReturnType()); - formulaPO.setValidateType(param.getValidateType()); - formulaPO.setExtendParam(param.getExtendParam()); - formulaPO.setFormula(param.getFormula()); - formulaPO.setDeleteType(NumberUtils.INTEGER_ZERO); - - Date now = new Date(); - formulaPO.setUpdateTime(now); - formulaPO.setCreator((long) user.getUID()); - getFormulaMapper().updateIgnoreNull(formulaPO); - List parameters = param.getParameters(); - //删除公式下的变量 - getFormulaVarMapper().deleteByFormulaId(id); - parameters.forEach(po -> { - po.setCreator((long) user.getUID()); - po.setCreateTime(now); - po.setUpdateTime(now); - getFormulaVarMapper().insertIgnoreNull(po); - }); - return formulaPO; + //防止参数名和字段名呈现一对多的问题 + if (CollectionUtils.isNotEmpty(parameters)) { + List notRepeatingNameSize = parameters.stream().map(FormulaVar::getFieldName).distinct().collect(Collectors.toList()); + if (notRepeatingNameSize.size() < parameters.size()) { + throw new SalaryRunTimeException("公式参数配置异常!参数名称重复,请清空公式内容后,再重新打开编辑"); + } + } + + String extendParam = param.getExtendParam(); + if (ReferenceTypeEnum.parseByValue(param.getReferenceType()) == ReferenceTypeEnum.SQL) { + + if (extendParam == null) { + throw new SalaryRunTimeException("未设置SQL返回值"); + } + + 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); + } + + if (StringUtils.isBlank(sqlReturnKey)) { + throw new SalaryRunTimeException("未设置SQL返回值"); + } + + //将select因XSS过滤造成的异常字符转换回来 + param.setFormula(param.getFormula().replaceAll("select", "select")); + param.setFormula(param.getFormula().replaceAll("SELECT", "SELECT")); + param.setFormula(param.getFormula().replaceAll("join", "join")); + param.setFormula(param.getFormula().replaceAll("JOIN", "JOIN")); + param.setFormula(param.getFormula().replaceAll("and", "and")); + param.setFormula(param.getFormula().replaceAll("AND", "AND")); + param.setFormula(param.getFormula().replaceAll("or", "or")); + param.setFormula(param.getFormula().replaceAll("OR", "OR")); + param.setFormula(param.getFormula().replaceAll("in", "in")); + param.setFormula(param.getFormula().replaceAll("IN", "IN")); + param.setFormula(param.getFormula().replaceAll("like", "like")); + param.setFormula(param.getFormula().replaceAll("LIKE", "like")); + param.setFormula(param.getFormula().replaceAll("exists", "exists")); + param.setFormula(param.getFormula().replaceAll("EXISTS", "EXISTS")); + } + + String formulaRunScript = param.getFormula(); + + for (FormulaVar po : parameters) { + formulaRunScript = formulaRunScript.replace(po.getFieldName(), po.getFieldId()); + } + + if (ReferenceTypeEnum.parseByValue(param.getReferenceType()) == ReferenceTypeEnum.SQL) { + if (formulaRunScript.contains(";") || formulaRunScript.contains("--")) { + throw new SalaryRunTimeException("SQL配置异常,请去除';'或者'--'"); + } + } + + + //返回类型 + String returnType = param.getReturnType(); + ReturnTypeEnum returnTypeEnum = ReturnTypeEnum.parseByValue(returnType); + + //验证公式是否可运行 + ExpressFormula test = ExpressFormula.builder().formulaRunScript(formulaRunScript).extendParam(extendParam).referenceType(param.getReferenceType()).build(); + Object run = null; + try { + run = getFormulaRunService(user).run(test, parameters, DataCollectionEmployee.builder().employeeId((long) user.getUID()).build()); + } catch (Exception e) { + log.error("express execute fail ", e); + throw new SalaryRunTimeException("公式测试运行出错,请检查公式配置!", e); + } + if (run != null && StringUtils.isNotBlank(String.valueOf(run)) && returnTypeEnum == ReturnTypeEnum.NUMBER) { + //返回结果不是数字 + if (!NumberUtils.isCreatable(String.valueOf(run))) { + throw new SalaryRunTimeException("返回结果不是数值"); + } + } + return run; } @Override diff --git a/src/com/engine/salary/web/SalaryFormulaController.java b/src/com/engine/salary/web/SalaryFormulaController.java index 04b3e07a3..5f653d3dc 100644 --- a/src/com/engine/salary/web/SalaryFormulaController.java +++ b/src/com/engine/salary/web/SalaryFormulaController.java @@ -1,7 +1,5 @@ package com.engine.salary.web; -import com.alibaba.fastjson.JSONObject; -import com.alibaba.fastjson.serializer.SerializerFeature; import com.engine.common.util.ServiceUtil; import com.engine.salary.entity.salaryformula.dto.ExpressFormulaDTO; import com.engine.salary.entity.salaryformula.param.SalaryFormulaFieldQueryParam; @@ -10,11 +8,8 @@ import com.engine.salary.entity.salaryformula.po.FormulaPO; import com.engine.salary.entity.salaryformula.po.FormulaVar; import com.engine.salary.util.ResponseResult; import com.engine.salary.wrapper.SalaryFormulaWrapper; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import io.swagger.v3.oas.annotations.parameters.RequestBody; import lombok.extern.slf4j.Slf4j; -import weaver.conn.RecordSetDataSource; import weaver.hrm.HrmUserVarify; import weaver.hrm.User; @@ -24,7 +19,6 @@ import javax.ws.rs.*; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -80,51 +74,19 @@ public class SalaryFormulaController { return new ResponseResult(user).run(getSalaryFormulaWrapper(user)::datasourceList); } + /** + * 测试公式 + * @param request + * @param response + * @param param + * @return + */ @POST - @Path("/checkSql") + @Path("/mock") @Produces(MediaType.APPLICATION_JSON) - public String checkFormula(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalaryFormulaSaveParam param) { + public String mock(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalaryFormulaSaveParam param) { User user = HrmUserVarify.getUser(request, response); - String result = ""; - Map map = new HashMap<>(); - - try { - String sql = request.getParameter("sql"); - String sqlReturnKey = request.getParameter("sqlReturnKey"); - String datasourceId = request.getParameter("datasourceId"); - RecordSetDataSource rs = new RecordSetDataSource(datasourceId); - log.info("sql run{},datasourceId:{},sqlReturnKey:{}", sql, datasourceId, sqlReturnKey); - map.put("sql", sql); - map.put("sqlReturnKey", sqlReturnKey); - map.put("datasourceId", datasourceId); - if (rs.executeSql(sql)) { - if (rs.next()) { - result = rs.getString(sqlReturnKey); - } - } - map.put("result", result); - } catch (Exception e) { - log.error("sql error", e); - Map apidatas = new HashMap<>(); - apidatas.put("status", false); - apidatas.put("errormsg", e.getMessage()); - return JSONObject.toJSONString(apidatas, SerializerFeature.DisableCircularReferenceDetect); - } - - Map apidatas = new HashMap<>(); - apidatas.put("status", true); - apidatas.put("data", map); - return getJsonString(apidatas); - } - - private static String getJsonString(Object apidatas) { - ObjectMapper mapper = new ObjectMapper(); - try { - return mapper.writeValueAsString(apidatas); - } catch (JsonProcessingException e) { - e.printStackTrace(); - } - return ""; + return new ResponseResult(user).run(getSalaryFormulaWrapper(user)::mock, param); } } diff --git a/src/com/engine/salary/wrapper/SalaryFormulaWrapper.java b/src/com/engine/salary/wrapper/SalaryFormulaWrapper.java index 5e66d5c9a..4f9b3c055 100644 --- a/src/com/engine/salary/wrapper/SalaryFormulaWrapper.java +++ b/src/com/engine/salary/wrapper/SalaryFormulaWrapper.java @@ -10,18 +10,23 @@ import com.engine.salary.entity.salaryformula.param.SalaryFormulaFieldQueryParam import com.engine.salary.entity.salaryformula.param.SalaryFormulaSaveParam; import com.engine.salary.entity.salaryformula.po.FormulaPO; import com.engine.salary.entity.salaryformula.po.FormulaVar; -import com.engine.salary.entity.salaryitem.po.SalaryItemPO; import com.engine.salary.entity.siaccount.dto.InsuranceAcctDetailImportFieldDTO; import com.engine.salary.exception.SalaryRunTimeException; +import com.engine.salary.service.FormulaRunService; import com.engine.salary.service.RemoteExcelService; import com.engine.salary.service.SalaryFormulaService; +import com.engine.salary.service.impl.FormulaRunServiceImpl; import com.engine.salary.service.impl.RemoteExcelServiceImpl; import com.engine.salary.service.impl.SalaryFormulaServiceImpl; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import weaver.hrm.User; import weaver.servicefiles.DataSourceXML; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; /** * 薪资项目 @@ -31,14 +36,19 @@ import java.util.*; * @author qiantao * @version 1.0 **/ +@Slf4j public class SalaryFormulaWrapper extends Service { private RemoteExcelService getRemoteExcelService(User user) { - return (RemoteExcelService) ServiceUtil.getService(RemoteExcelServiceImpl.class, user); + return ServiceUtil.getService(RemoteExcelServiceImpl.class, user); } private SalaryFormulaService getSalaryFormulaService(User user) { - return (SalaryFormulaService) ServiceUtil.getService(SalaryFormulaServiceImpl.class, user); + return ServiceUtil.getService(SalaryFormulaServiceImpl.class, user); + } + + private FormulaRunService getFormulaRunService(User user) { + return ServiceUtil.getService(FormulaRunServiceImpl.class, user); } private SalaryItemBiz salaryItemBiz = new SalaryItemBiz(); @@ -93,7 +103,7 @@ public class SalaryFormulaWrapper extends Service { //获取福利类薪资项目 List list = getRemoteExcelService(user).fieldList(param.getSourceId(), param.getExtendParam()); //提取出福利类项目名称 - for(FormulaVar formulaVar : list) { + for (FormulaVar formulaVar : list) { InsuranceAcctDetailImportFieldDTO insuranceAcctDetailImportFieldDTO = new InsuranceAcctDetailImportFieldDTO(); // insuranceAcctDetailImportFieldDTO.setFieldId(formulaVar.getFieldId()); insuranceAcctDetailImportFieldDTO.setSalaryItemName(formulaVar.getName()); @@ -108,4 +118,8 @@ public class SalaryFormulaWrapper extends Service { return welfareList; } + + public Object mock(SalaryFormulaSaveParam param) { + return getSalaryFormulaService(user).mock(param); + } }