feat:新增数据采集产能
parent
5b7456c50a
commit
a86d70c0a6
@ -0,0 +1,96 @@
|
||||
package cn.iocoder.yudao.module.iot.framework.util;
|
||||
|
||||
// FormulaEvalUtils
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Map;
|
||||
|
||||
public class FormulaEvalUtils {
|
||||
|
||||
private FormulaEvalUtils() {}
|
||||
|
||||
public static BigDecimal evalExpr(JSONObject node, Map<String, Object> vars) {
|
||||
if (node == null) return BigDecimal.ZERO;
|
||||
|
||||
if (node.containsKey("field")) {
|
||||
Object value = vars.get(node.getString("field"));
|
||||
return toBigDecimal(value);
|
||||
}
|
||||
|
||||
if (node.containsKey("value")) {
|
||||
return toBigDecimal(node.get("value"));
|
||||
}
|
||||
|
||||
String op = node.getString("op");
|
||||
BigDecimal left = evalExpr(node.getJSONObject("left"), vars);
|
||||
BigDecimal right = evalExpr(node.getJSONObject("right"), vars);
|
||||
return apply(left, right, op);
|
||||
}
|
||||
|
||||
//
|
||||
public static BigDecimal evalStepArrayByCode(JSONArray steps, Map<String, Object> vars) {
|
||||
if (steps == null || steps.isEmpty()) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
BigDecimal result = null;
|
||||
String pendingBigOp = null; // 上一步的 bigOperator
|
||||
|
||||
for (int i = 0; i < steps.size(); i++) {
|
||||
JSONObject step = steps.getJSONObject(i);
|
||||
if (step == null) continue;
|
||||
|
||||
String code = step.getString("code");
|
||||
String operator = step.getString("operator");
|
||||
Object valueObj = step.get("value");
|
||||
|
||||
BigDecimal codeValue = readCodeValue(code, vars);
|
||||
BigDecimal value = toBigDecimal(valueObj);
|
||||
BigDecimal current = apply(codeValue, value, operator); // A/B/C
|
||||
|
||||
if (result == null) {
|
||||
result = current;
|
||||
} else {
|
||||
result = apply(result, current, pendingBigOp); // 用上一项的 bigOperator
|
||||
}
|
||||
|
||||
pendingBigOp = step.getString("bigOperator"); // 留给下一轮使用
|
||||
}
|
||||
|
||||
return result == null ? BigDecimal.ZERO : result;
|
||||
}
|
||||
|
||||
private static BigDecimal readCodeValue(String code, Map<String, Object> vars) {
|
||||
if (StringUtils.isBlank(code) || vars == null) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
return toBigDecimal(vars.get(code));
|
||||
}
|
||||
|
||||
private static BigDecimal toBigDecimal(Object raw) {
|
||||
if (raw == null || StringUtils.isBlank(String.valueOf(raw))) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
return new BigDecimal(String.valueOf(raw));
|
||||
}
|
||||
|
||||
private static BigDecimal apply(BigDecimal left, BigDecimal right, String op) {
|
||||
if (StringUtils.isBlank(op)) {
|
||||
return left;
|
||||
}
|
||||
switch (op) {
|
||||
case "+": return left.add(right);
|
||||
case "-": return left.subtract(right);
|
||||
case "*": return left.multiply(right);
|
||||
case "/":
|
||||
if (right.compareTo(BigDecimal.ZERO) == 0) return BigDecimal.ZERO;
|
||||
return left.divide(right, 6, RoundingMode.HALF_UP);
|
||||
default: throw new IllegalArgumentException("Unsupported op: " + op);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue