在进行BOM计算等需要用到定义计算公式并进行解析计算,下面是让用户定义字符串表达式,通过解析字符串表达式实现计算,要求参数代码、计算符号、函数之间用空格隔开,参数代码不能是纯数字(如果是纯数字不会进行转换),可以使用MySql的函数。
基础代码如下:
private BigDecimal optFunStr(FunStrAndParamList reqDTO) {
BigDecimal result = new BigDecimal("0");
//用于判断字符串是否可以转换为数值
String regularExpression = "(^[+-]?[0-9]+)|(^[+-]?[0-9]+\\.[0-9]+)";
//对应的已经获取了参数值列表
List<Param> paramList = new ArrayList<>();
paramList = reqDTO.getParamList();
//公式
String formula = reqDTO.getFunStr().replaceAll("\\s{1,}", " ").trim();
String[] fArrs = formula.split("\\s");
String formulaTran = "";
for (String fArr : fArrs) {
String fArrTran = "";
//判断是否是运算符
List<String> opeSymbols = Arrays.asList("+", "-", "*", "/", "=", ">", "<", ">=", "<=", "<>", "(", ")", "()");
Long check1 = opeSymbols.stream().filter(x -> fArr.equals(x)).count();
if (check1 > 0L) {
fArrTran = fArr;
} else {
//判断是否为数值
Boolean check2 = fArr.matches(regularExpression);
if (check2) {
fArrTran = fArr;
} else {
Param paramFind = paramList.stream().filter(x ->
fArr.trim().equals(x.getParamCode().trim())).findFirst().orElse(null);
fArrTran = paramFind.getParamValue().trim();
}
}
formulaTran = formulaTran + " " + fArrTran;
}
//利用解析后的公式计算
if (0 != formulaTran.length()) {
result = this.optfunStrMapper.optFunStr(formulaTran);
}
return result;
}