公司有这样一个需求:需要一个接口,通过传入表达式来计算相应的值,并将计算的结果展示在图表上。每个指标对应一大堆数据,页面设计如下
我与前端程序员约定好参数格式,返回参数等,着手开发接口,代码如下
/**
* 四则运算
* create by ly
* @Param [dataIds 参与计算的指标, mathSigns 四则运算符, expression 表达式]
* @return cn.chinatsi.datamanager.vo.JsonFormatVo
*/
public JsonFormatVo arithmetic(List<String> dataIds,List<String> mathSigns,String expression,String beginDate,String endDate,String userId){
IndexShowDataVo indexShowDataVo = IndexShowDataVo.builder().build();
Map<String,List<Map<String, Object>>> dataMap = new HashMap<>();
//获取指标数据
for (String dataId : dataIds) {
TAllDataN tAllDataN = tAllDataNMapper.selectByPrimaryKey(dataId);
if(tAllDataN!=null){
//获取指标数据
List<Map<String,Object>> maps = connectUrl(dataId, beginDate, endDate)
if(!CollectionUtils.isEmpty(maps)){
dataMap.put(tAllDataN.getDataId(),maps);
}
}
}
//代入数据后的表达式集
List<Map<String,String>> expressionList = new ArrayList<>();
//获取日期集合
List<String> dateList = DateUtil.betweenDateList(beginDate, endDate);
if(!dataMap.isEmpty()){
for (String date : dateList) {
String ex = expression;
int i =0;
//循环日期,获取指定日期各个指标的数据,并代入表达式
for (Map.Entry<String, List<Map<String, Object>>> entry : dataMap.entrySet()) {
String key = entry.getKey();//指标名称
List<Map<String, Object>> value = entry.getValue();//指标数据集
//整理指标数据集
Map<String,Map<String, Object>> tempMap = new HashMap<>();
for (Map<String, Object> objectMap : value) {
if(objectMap.get("rq")!=null){
tempMap.put(objectMap.get("rq").toString(),objectMap);
}
}
if(tempMap.containsKey(date)){
//将数值代入对应表达式中
ex = ex.replace(key,"("+tempMap.get(date).get("data").toString()+")");
i++;
}
}
if(i==dataMap.size()){
//如果某一个指标不存在日期,那么就不显示这个日期
Map<String,String> map = new HashMap<>();
map.put(date,ex);
expressionList.add(map);
}
}
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
//获取js引擎
ScriptEngine js = scriptEngineManager.getEngineByName("js");
//计算表达式
for (Map<String, String> dataAndEx : expressionList) {
for (Map.Entry<String, String> entryEx : dataAndEx.entrySet()) {
String key = entryEx.getKey();//日期
String value = entryEx.getValue();//表达式
try {
String result = js.eval(value).toString();
dataAndEx.put(key,result);//将计算后的结果放回
} catch (ScriptException e) {
e.printStackTrace();
return new JsonFormatVo("117","计算失败,请检查表达式",null);
}
}
}
indexShowDataVo.setDataList(expressionList);
}
return new JsonFormatVo("0","计算成功",indexShowDataVo);
}
计算结果
其实单用java也是可以计算四则公式的,这就需要编写算法了,需要的消耗的人力比较多,相比较,使用成熟的工具才是最正确的选择,其它的工具还有jexl3表达式引擎、groovy规则引擎等。
您的赞和关注是对我创作的最大肯定谢谢大家