一.输入示列脚本
if(实际重量==null || 实际重量<=0){
实际重量=eclp回传重量;
}
if(实际重量==null || 实际重量<=0){
throw new Exception("实际重量为空");
}
计费重量=serv.round(实际重量,1);
运费=首重价格;
if(计费重量>20 && 计费重量<=60){
运费=serv.round(首重价格+(计费重量-20)*续重单价1,2);
}
if(计费重量>60){
运费=serv.round(首重价格+ 40*续重单价1+(计费重量-60)*续重单价2,2);
}
return 运费;
二、封装参数,使用groovy执行脚本
代码如下:
package com.jd.jcloud.groovy;
import com.jd.jcloud.common.exception.BusinessException;
import com.jd.jcloud.common.utils.security.Md5Utils;
import com.jd.jcloud.groovy.groovy.ReRuleRunServiceEx;
import com.jd.jcloud.groovy.service.Const;
import com.jd.jcloud.groovy.service.ReRuleRunService;
import com.jd.jcloud.groovy.util.StringUtil;
import groovy.lang.Binding;
import groovy.lang.GroovyClassLoader;
import groovy.lang.Script;
import org.codehaus.groovy.runtime.InvokerHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
/**
* @Author
* @Date 2024/4/16 18:08
* @Version 1.0
*/
@Service
public class GroovyService {
private static GroovyClassLoader gcl = new GroovyClassLoader();
@Autowired
private ReRuleRunServiceEx reRuleRunService;
/**
* ruleBody 脚本类似于java 代码
* eg:
*/
public Object runRule(String formula,double weight) {
Map<String, Object> input=new HashMap<>();
Object ruleId = input.get("ruleId");
// 加载类需要的参数
Binding binding = new Binding();
for (String key : input.keySet()) {
binding.setVariable(key, input.get(key));
}
binding.setVariable("serv", reRuleRunService);
binding.setVariable("实际重量", weight);
binding.setVariable("eclp回传重量", 2.111);
binding.setVariable("首重价格", 2);
binding.setVariable("续重单价1", 4);
binding.setVariable("续重单价2", 6);
String ruleBody = StringUtil.htmlDecode(formula);
String md5 = Md5Utils.hash(formula);
try{
Class clazz = gcl.parseClass(ruleBody, md5);
Script methodScript = InvokerHelper.createScript(clazz, binding);
return methodScript.run();
}catch (Exception e){
throw new BusinessException("公式、方法处理失败:" + e.getMessage());
}
}
public Object runRule(double weight){
String formula="if(实际重量==null || 实际重量<=0){\n" +
" 实际重量=eclp回传重量;\n" +
"}\n" +
"if(实际重量==null || 实际重量<=0){\n" +
" throw new Exception(\"实际重量为空\");\n" +
"}\n" +
"计费重量=serv.round(实际重量,1);\n" +
"运费=首重价格;\n" +
"if(计费重量>20 && 计费重量<=60){\n" +
" 运费=serv.round(首重价格+(计费重量-20)*续重单价1,2);\n" +
"}\n" +
"if(计费重量>60){\n" +
" 运费=serv.round(首重价格+ 40*续重单价1+(计费重量-60)*续重单价2,2);\n" +
"} \n" +
"return 运费;";
return this.runRule(formula,weight);
}
}
三、脚本解析
实际脚本类似于java 代码,可注入java中的服务用于脚本调用,参数通过Binging进行传入。
Binging 绑定服务serv,脚本直接调用服务中的方法。
脚本可通过前端页面用户输入获得。