You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
4.7 KiB
Java
130 lines
4.7 KiB
Java
package com.supervision.utils;
|
|
|
|
import com.supervision.common.constant.IndexRuleConstants;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.springframework.expression.ExpressionParser;
|
|
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
|
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
|
|
|
import java.util.Set;
|
|
|
|
import static com.supervision.common.constant.IndexRuleConstants.LOGIC_AND;
|
|
import static com.supervision.common.constant.IndexRuleConstants.LOGIC_OR;
|
|
|
|
@Slf4j
|
|
public class CalculationUtil {
|
|
|
|
/**
|
|
* 计算表达式结果
|
|
*
|
|
* @param leftOperand 左操作数
|
|
* @param operator 操作符
|
|
* @param rightOperand 右操作数
|
|
* @return 计算结果
|
|
*/
|
|
public static boolean evaluateExpression(String leftOperand, String operator, String rightOperand) {
|
|
String expression = switch (operator) {
|
|
case IndexRuleConstants.OPERATOR_GT -> // ">"
|
|
"#leftOperand > #rightOperand";
|
|
case IndexRuleConstants.OPERATOR_GE -> // ">="
|
|
"#leftOperand >= #rightOperand";
|
|
case IndexRuleConstants.OPERATOR_LT -> // "<"
|
|
"#leftOperand < #rightOperand";
|
|
case IndexRuleConstants.OPERATOR_LE -> // "<="
|
|
"#leftOperand <= #rightOperand";
|
|
case IndexRuleConstants.OPERATOR_EQ -> // "="
|
|
"#leftOperand == #rightOperand";
|
|
case IndexRuleConstants.OPERATOR_NE -> // "!="
|
|
"#leftOperand != #rightOperand";
|
|
case IndexRuleConstants.OPERATOR_EARLY -> // "早于"
|
|
"#leftOperand < #rightOperand";
|
|
case IndexRuleConstants.OPERATOR_LATE -> // "晚于"
|
|
"#leftOperand > #rightOperand";
|
|
case IndexRuleConstants.OPERATOR_CONTAIN -> // "包含"
|
|
"#leftOperand.contains(#rightOperand)";
|
|
default -> throw new UnsupportedOperationException("不支持的操作符: " + operator);
|
|
};
|
|
|
|
// 判断操作符并构造相应的SpEL表达式
|
|
|
|
log.info("Expression: [{}]", expression);
|
|
|
|
// 初始化SpEL解析器
|
|
ExpressionParser parser = new SpelExpressionParser();
|
|
StandardEvaluationContext context = new StandardEvaluationContext();
|
|
// 判断并转换变量类型
|
|
Object leftValue = parseOperand(leftOperand);
|
|
Object rightValue = parseOperand(rightOperand);
|
|
context.setVariable("leftOperand", leftValue);
|
|
context.setVariable("rightOperand", rightValue);
|
|
|
|
// 计算结果
|
|
return Boolean.TRUE.equals(parser.parseExpression(expression).getValue(context, Boolean.class));
|
|
}
|
|
|
|
/**
|
|
* 辅助方法:动态解析操作数类型
|
|
*
|
|
* @param operand 操作数
|
|
* @return 解析结果
|
|
*/
|
|
private static Object parseOperand(String operand) {
|
|
if (operand == null) {
|
|
return null;
|
|
}
|
|
try {
|
|
// 尝试解析为数字(支持整数和小数)
|
|
if (operand.contains(".")) {
|
|
return Double.valueOf(operand);
|
|
} else {
|
|
return Integer.valueOf(operand);
|
|
}
|
|
} catch (NumberFormatException e) {
|
|
// 如果解析失败,返回原始字符串
|
|
return operand;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 计算布尔值集合的逻辑运算结果
|
|
*
|
|
* @param booleanSet 布尔值集合
|
|
* @param logic 逻辑运算符
|
|
* @return 计算结果
|
|
*/
|
|
public static boolean calculateBooleanSet(Set<Boolean> booleanSet, String logic) {
|
|
// 判断是否为空
|
|
if (booleanSet == null || booleanSet.isEmpty()) {
|
|
return false;
|
|
}
|
|
|
|
// 判断是"且"还是"或"
|
|
String operator;
|
|
if (LOGIC_AND.equals(logic)) {
|
|
operator = " and ";
|
|
} else if (LOGIC_OR.equals(logic)) {
|
|
operator = " or ";
|
|
} else {
|
|
throw new IllegalArgumentException("Invalid logic value: [" + logic + "], use 1 for AND, 2 for OR.");
|
|
}
|
|
|
|
// 构建表达式
|
|
StringBuilder expressionBuilder = new StringBuilder();
|
|
boolean first = true;
|
|
for (Boolean bool : booleanSet) {
|
|
if (!first) {
|
|
expressionBuilder.append(operator);
|
|
}
|
|
expressionBuilder.append(bool);
|
|
first = false;
|
|
}
|
|
|
|
// 初始化SpEL解析器
|
|
ExpressionParser parser = new SpelExpressionParser();
|
|
StandardEvaluationContext context = new StandardEvaluationContext();
|
|
|
|
// 计算结果
|
|
return Boolean.TRUE.equals(parser.parseExpression(expressionBuilder.toString()).getValue(context, Boolean.class));
|
|
}
|
|
}
|