新增计算公式

This commit is contained in:
jinqiming 2021-09-30 11:15:09 +08:00
parent 00d2749194
commit fe2c647102
5 changed files with 122 additions and 0 deletions

View File

@ -42,6 +42,7 @@
<lombok.version>1.18.10</lombok.version>
<zhyd.oauth.version>1.15.6</zhyd.oauth.version>
<jsqlparser.version>1.4</jsqlparser.version>
<googlecode.aviator.version>2.3.3</googlecode.aviator.version>
</properties>
<!-- 依赖声明 -->
@ -329,6 +330,13 @@
<artifactId>flowable-json-converter</artifactId>
<version>${flowable.version}</version>
</dependency>
<!--Aviator是一个轻量级、高性能的Java表达式执行引擎它动态地将表达式编译成字节码并运行。可被用于动态的公式计算、规则执行和过滤等场景-->
<dependency>
<groupId>com.googlecode.aviator</groupId>
<artifactId>aviator</artifactId>
<version>${googlecode.aviator.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

View File

@ -151,6 +151,11 @@
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
</dependency>
<dependency>
<groupId>com.googlecode.aviator</groupId>
<artifactId>aviator</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,20 @@
package com.snow.common.annotation;
import java.lang.annotation.*;
/**
* @author qimingjin
* @Title:
* @Description:
* @date 2021/9/30 10:50
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
@Documented
public @interface FormulaChinese {
/**
* 计算汉化名称
* @return
*/
String name() default "";
}

View File

@ -0,0 +1,41 @@
package com.snow.common.utils.formula;
import com.snow.common.annotation.FormulaChinese;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
/**
* 表达式计算引擎
*/
@Slf4j
public class MathEnv {
/**
* 根据对象获取变量和值
* @param o
* @return
*/
public Map<String, Object> getEnv(Object o) {
Map<String, Object> env = new HashMap<>(30);
Field[] fields = o.getClass().getDeclaredFields();
for (Field f : fields) {
FormulaChinese annotation = f.getAnnotation(FormulaChinese.class);
if (null != annotation) {
String name = annotation.name();
f.setAccessible(true);
Object fieldVal = null;
try {
fieldVal = f.get(o);
} catch (IllegalAccessException e) {
log.info("exception:{}", e);
throw new RuntimeException(e);
}
env.put(name, fieldVal);
}
}
return env;
}
}

View File

@ -0,0 +1,48 @@
package com.snow.common.utils.formula;
import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.Expression;
import lombok.extern.slf4j.Slf4j;
import java.math.BigDecimal;
import java.util.Map;
/**
* 表达式计算引擎
*/
@Slf4j
public class MathFormula {
/**
* 通过对象执行公式
* @param mathformula
* @param o
* @return
*/
public static BigDecimal executeFormula(String mathformula, Object o) {
MathEnv mathEnv = new MathEnv();
Map<String, Object> env = mathEnv.getEnv(o);
return compileAndExecute(mathformula, env);
}
/**
* 通过Map执行公式
* @param mathFormula
* @param env
* @return
*/
private static BigDecimal compileAndExecute(String mathFormula, Map<String, Object> env) {
// 打印计算公式
log.info("**************************************************");
log.info("@@传入的计算公式 => {}", mathFormula);
Expression compiledExp = AviatorEvaluator.compile(mathFormula);
// 打印变量和值
env.entrySet().forEach(e ->log.info("{} => {}", e.getKey(), e.getValue()));
// 打印结果
BigDecimal result = (BigDecimal) compiledExp.execute(env);
log.info("@@根据公式计算结果 => {}", result);
log.info("**************************************************");
return result;
}
}