package com.iailab.module.data.point.collection.handler; import com.iailab.module.data.common.enums.DataTypeEnum; import com.iailab.module.data.common.enums.JsErrorCode; import com.iailab.module.data.common.utils.JavaScriptHandler; import com.iailab.module.data.point.collection.utils.GenInfluxPointValueUtils; import com.iailab.module.data.point.dto.DaPointDTO; import com.iailab.module.data.point.service.DaPointService; import com.iailab.module.data.influxdb.pojo.InfluxPointValuePOJO; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import javax.annotation.Resource; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import java.math.BigDecimal; import java.util.*; /** * 计算点处理 * * @author PanZhibao * @Description * @createTime 2023年05月03日 17:40:00 */ @Slf4j @Component public class CalculateHandle { @Resource private DaPointService daPointService; @Resource private MeasureHandle measureHandle; @Resource private ConstantHandle constantHandle; @Resource private JavaScriptHandler javaScriptHandler; public static final String regex = "[+\\-\\*\\/\\(\\)\\&\\|\\>\\<]"; public List handle(Date collectTime, List dtos, Map dataMap) { List result = new ArrayList<>(); try { log.info("计算点处理开始"); if (CollectionUtils.isEmpty(dtos)) { return result; } dtos.forEach(dto -> { try { Object value = singleCompute(dto, dataMap); InfluxPointValuePOJO pojo = GenInfluxPointValueUtils.getByPoint(dto, value); pojo.setTimestamp(collectTime.toInstant()); result.add(pojo); } catch (Exception ex) { ex.printStackTrace(); log.info("计算点异常!PointNo=" + dto.getPointNo()); } }); log.info("计算点处理结束"); } catch (Exception ex) { ex.printStackTrace(); log.info("计算点处理异常!"); } return result; } private Object singleCompute(DaPointDTO dto, Map dataMap) { String expression = dto.getExpression(); String[] arr = expression.split(regex); for (int i = 0; i < arr.length; i++) { String s = arr[i]; if (StringUtils.isNotBlank(s) && dataMap.containsKey(s)) { expression = expression.replace(s, dataMap.get(s).toString()); } } expression = expression.replace("&", "&&"); expression = expression.replace("|", "||"); expression = expression.replace("False", "false"); expression = expression.replace("True", "true"); log.info("PointNo=" + dto.getPointNo() + ";expression=" + expression); String result = javaScriptHandler.eval(expression); log.info("result=" + result); if (result == null) { return null; } else if (result.contains(JsErrorCode.Infinity.name()) || result.contains(JsErrorCode.NaN.name())) { log.info("计算异常,使用默认值"); return dto.getDefaultValue() == null ? BigDecimal.ZERO : dto.getDefaultValue(); } else { if (DataTypeEnum.INT.getCode().equals(dto.getDataType())) { return new BigDecimal(result).intValue(); } else if (DataTypeEnum.FLOAT.getCode().equals(dto.getDataType())) { return new BigDecimal(result).setScale(10, BigDecimal.ROUND_UP).doubleValue(); } else if (DataTypeEnum.BOOLEAN.getCode().equals(dto.getDataType())) { return Boolean.parseBoolean(result); } } return result; } public Map getCurrent(List pointNos) { Map data = new HashMap<>(); List pointMathList = daPointService.getMathPoint(pointNos); if (CollectionUtils.isEmpty(pointMathList)) { return data; } pointMathList.forEach(item -> { data.put(item.getPointNo(), singleCompute(item)); }); return data; } private Object singleCompute(DaPointDTO dto) { Map dataMap = new HashMap<>(); String expression = dto.getExpression(); String[] arr = expression.split(regex); for (int i = 0; i < arr.length; i++) { String s = arr[i]; if (StringUtils.isBlank(s)) { continue; } List pointNos = new ArrayList<>(); pointNos.add(s); dataMap.putAll(measureHandle.getCurrent(pointNos)); dataMap.putAll(constantHandle.getCurrent(pointNos)); expression = expression.replace(s, dataMap.get(s).toString()); } expression = expression.replace("&", "&&"); expression = expression.replace("|", "||"); expression = expression.replace("False", "false"); expression = expression.replace("True", "true"); log.info("PointNo=" + dto.getPointNo() + ";expression=" + expression); String result = javaScriptHandler.eval(expression); log.info("result=" + result); if (result == null) { return null; } else if (result.contains(JsErrorCode.Infinity.name()) || result.contains(JsErrorCode.NaN.name())) { log.info("计算异常,使用默认值"); return dto.getDefaultValue() == null ? BigDecimal.ZERO : dto.getDefaultValue(); } else { if (DataTypeEnum.INT.getCode().equals(dto.getDataType())) { return new BigDecimal(result).intValue(); } else if (DataTypeEnum.FLOAT.getCode().equals(dto.getDataType())) { return new BigDecimal(result).setScale(10, BigDecimal.ROUND_UP).doubleValue(); } else if (DataTypeEnum.BOOLEAN.getCode().equals(dto.getDataType())) { return Boolean.parseBoolean(result); } } return result; } }