kaiyu
2021-12-28 6450fec60b8dc7e6d31779bcfe3b23b3f665ebaf
screen-api
更新单位转换代码
1 files deleted
1 files added
5 files modified
270 ■■■■ changed files
screen-api/src/main/java/com/moral/api/controller/AqiController.java 14 ●●●●● patch | view | raw | blame | history
screen-api/src/main/java/com/moral/api/kafka/consumer/CruiserDataConsumer.java 2 ●●● patch | view | raw | blame | history
screen-api/src/main/java/com/moral/api/kafka/consumer/SecondDataConsumer.java 5 ●●●● patch | view | raw | blame | history
screen-api/src/main/java/com/moral/api/pojo/vo/cityAQI/BarChartTableOfPollutionLevelVO.java 2 ●●● patch | view | raw | blame | history
screen-api/src/main/java/com/moral/api/service/impl/CityAqiServiceImpl.java 19 ●●●● patch | view | raw | blame | history
screen-api/src/main/java/com/moral/api/utils/UnitConvertUtils.java 180 ●●●●● patch | view | raw | blame | history
screen-common/src/main/java/com/moral/util/UnitConvertUtils.java 48 ●●●●● patch | view | raw | blame | history
screen-api/src/main/java/com/moral/api/controller/AqiController.java
@@ -109,6 +109,13 @@
        return ResultMessage.ok(VO);
    }
    /**
    * @Description: 获取城市优良天气占比的柱状图数据
            * @Param: [form]
            * @return: com.moral.constant.ResultMessage
            * @Author: 陈凯裕
            * @Date: 2021/11/22
            */
    @GetMapping("queryBarChartOfPollutionLevel")
    public ResultMessage queryBarChartOfPollutionLevel(QueryChartOfPollutionLevelForm form){
        //判断是否缺少参数
@@ -123,6 +130,13 @@
    }
    /**
    * @Description: 获取城市优良天气占比的柱状图下的表格数据
            * @Param: [form]
            * @return: com.moral.constant.ResultMessage
            * @Author: 陈凯裕
            * @Date: 2021/11/22
            */
    @GetMapping("queryBarChatTableOfPollutionLevel")
    public ResultMessage queryBarChatTableOfPollutionLevel(QueryChartOfPollutionLevelForm form){
        //判断是否缺少参数
screen-api/src/main/java/com/moral/api/kafka/consumer/CruiserDataConsumer.java
@@ -1,5 +1,6 @@
package com.moral.api.kafka.consumer;
import com.moral.api.utils.UnitConvertUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.common.TopicPartition;
@@ -22,7 +23,6 @@
import com.moral.api.entity.UnitConversion;
import com.moral.api.websocket.CruiserWebSocketServer;
import com.moral.constant.KafkaConstants;
import com.moral.util.UnitConvertUtils;
/*
 * 走航车数据消费者
screen-api/src/main/java/com/moral/api/kafka/consumer/SecondDataConsumer.java
@@ -4,15 +4,12 @@
import com.moral.api.entity.Device;
import com.moral.api.entity.Sensor;
import com.moral.api.entity.UnitConversion;
import com.moral.api.utils.UnitConvertUtils;
import com.moral.api.websocket.SingleDeviceServer;
import com.moral.util.UnitConvertUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.consumer.Consumer;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.common.TopicPartition;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.listener.ConsumerSeekAware;
import org.springframework.stereotype.Component;
screen-api/src/main/java/com/moral/api/pojo/vo/cityAQI/BarChartTableOfPollutionLevelVO.java
@@ -89,7 +89,7 @@
        vo.setSerious(serious);
        vo.setServer(server);
        return vo;
    }
}
screen-api/src/main/java/com/moral/api/service/impl/CityAqiServiceImpl.java
@@ -135,6 +135,21 @@
        Map<String, Object> value = (Map<String, Object>) redisTemplate.opsForHash().get(RedisConstants.CITY_AQI, String.valueOf(regionCode));
        if (value == null)
            value = queryCityAqiByRegionCodeFromDB(regionCode);
        //如果地区码是县级市则转换到市级在进行查询
        if (value == null) {
            String regionCodeStr = String.valueOf(regionCode);
            String end = regionCodeStr.substring(regionCodeStr.length() - 2, regionCodeStr.length());
            if (!end.equals(00)) {
                regionCodeStr = regionCodeStr.substring(0, regionCodeStr.length() - 2);
                regionCodeStr += "00";
                regionCode = Integer.parseInt(regionCodeStr);
                value = (Map<String, Object>) redisTemplate.opsForHash().get(RedisConstants.CITY_AQI, String.valueOf(regionCode));
                if (value == null)
                    value = queryCityAqiByRegionCodeFromDB(regionCode);
            }else{
                return null;
            }
        }
        //根据AQI计算污染等级
        if (value == null || value.get("AQI") == null)
            return null;
@@ -754,7 +769,7 @@
    /**
     * @Description: 计算6参平均值
     * @Param: [cityAqiList]
     * @return: java.util.Map<java.lang.String, java.lang.Double>
     * @return: java.util.Map<java.lang.String       ,               java.lang.Double>
     * 返回值key为sensorCode,value为值
     * @Author: 陈凯裕
     * @Date: 2021/11/2
@@ -808,7 +823,7 @@
    /**
     * @Description: 从数据库查询数据
     * @Param: [regionCode]
     * @return: java.util.Map<java.lang.String, java.lang.Object>
     * @return: java.util.Map<java.lang.String       ,               java.lang.Object>
     * @Author: 陈凯裕
     * @Date: 2021/10/28
     */
screen-api/src/main/java/com/moral/api/utils/UnitConvertUtils.java
New file
@@ -0,0 +1,180 @@
package com.moral.api.utils;
import com.moral.api.entity.Device;
import com.moral.api.entity.Sensor;
import com.moral.api.entity.UnitConversion;
import com.moral.api.entity.Version;
import com.moral.constant.RedisConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import javax.annotation.PostConstruct;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
 * @ClassName UnitConvertUtils
 * @Description TODO
 * @Author 陈凯裕
 * @Date 2021/12/27 16:17
 * @Version TODO
 **/
@Component
public class UnitConvertUtils {
    /*
     * 小数点后保留位数
     * */
    public static Integer num = 3;
    private static RedisTemplate redisTemplate;
    private static List<UnitConversion> unitConversions;
    private static Map<String,Device> devices;
    @PostConstruct
    public void init() {
        UnitConvertUtils.unitConversions = redisTemplate.opsForList().range(RedisConstants.UNIT_CONVERSION, 0, -1);
        devices = redisTemplate.opsForHash().entries(RedisConstants.DEVICE_INFO);
    }
    @Autowired
    public void setRedisTemplate(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }
    /**
     * @Description: 转换数据单位到对应的显示单位
     * @Param: [mac, data]
     * @return: java.util.Map<java.lang.String                                                               ,                                                               java.lang.Object>
     * @Author: 陈凯裕
     * @Date: 2021/12/27
     */
    public static Map<String, Object> convertUnitToShowUnit(String mac, Map<String, Object> data) {
        if (mac == null || data == null)
            return null;
        Device device = devices.get(mac);
        //如果缓存中没有设备则刷新缓存
        if(device==null){
            devices = redisTemplate.opsForHash().entries(RedisConstants.DEVICE_INFO);
            device = devices.get(mac);
            if(device==null)
                return null;
        }
        Version version = device.getVersion();
        //型号中所有的因子
        List<Sensor> sensors = version.getSensors();
        //遍历型号中所有的因子,给数据做单位转换
        for (Sensor sensor : sensors) {
            String unitKey = sensor.getUnitKey();//原始单位
            String showUnitKey = sensor.getShowUnitKey();//显示单位
            //如果原始单位和显示单位不一致则进行单位转换
            if (!unitKey.equals(showUnitKey)) {
                Object valueObject = data.get(sensor.getCode());
                //如果因子不存在则跳过本次循环,进行下一个因子处理
                if (valueObject == null)
                    continue;
                //获取计算公式
                String formula = getFormula(sensor);
                if (formula == null)
                    continue;
                //获取对应因子数据
                Double value = Double.valueOf(String.valueOf(valueObject));
                //对数据转换格式
                String valueStr = new BigDecimal(value).toString();
                //用公式对原始数据进行转换
                String calculateValue = calculate(valueStr, formula);
                if(calculateValue==null)
                    continue;
                value = Double.parseDouble(calculateValue);
                data.put(sensor.getCode(),value);
            } else
                continue;
        }
        return data;
    }
    /**
     * @Description: 获取单位转换的公式
     * @Param: [sensor]
     * @return: java.lang.String
     * @Author: 陈凯裕
     * @Date: 2021/12/28
     */
    private static String getFormula(Sensor sensor) {
        String formula = sensor.getFormula();
        if (!ObjectUtils.isEmpty(formula))
            return formula;
        List<UnitConversion> tmpUnitConversions = new ArrayList<>();
        for (UnitConversion unitConversion : unitConversions) {
            if (unitConversion.getOriginalUnitKey().equals(sensor.getUnitKey()) && unitConversion.getTargetUnitKey().equals(sensor.getShowUnitKey()))
                tmpUnitConversions.add(unitConversion);
        }
        //如果缓存没有则刷新程序内部缓存
        if (tmpUnitConversions.size() == 0) {
            refreshUnitConversionCache();
        }
        //重新查找公式
        for (UnitConversion unitConversion : unitConversions) {
            if (unitConversion.getOriginalUnitKey().equals(sensor.getUnitKey()) && unitConversion.getTargetUnitKey().equals(sensor.getShowUnitKey()))
                tmpUnitConversions.add(unitConversion);
        }
        //如果没有则直接返回null
        if (tmpUnitConversions.size() == 0)
            return null;
        //如果只有一个则是没有专用因子
        if (unitConversions.size() == 1)
            return unitConversions.get(0).getFormula();
        //根据专用因子剔除
        for (UnitConversion unitConversion : unitConversions) {
            if (unitConversion.getSensorCode().equals(sensor.getCode()))
                return unitConversion.getFormula();
        }
        return null;
    }
    /**
     * @Description: 刷新公式内部缓存
     * @Param: []
     * @return: void
     * @Author: 陈凯裕
     * @Date: 2021/12/28
     */
    private static void refreshUnitConversionCache() {
        UnitConvertUtils.unitConversions = redisTemplate.opsForList().range(RedisConstants.UNIT_CONVERSION, 0, -1);
    }
    /**
     * @Description: value为要转换的值,format为公式
     * @Param: [value, format]
     * @return: java.lang.Double
     * @Author: 陈凯裕
     * @Date: 2021/7/5
     */
    public static String calculate(String value, String formula) {
        if (ObjectUtils.isEmpty(formula))
            return null;
        ScriptEngine jse = new ScriptEngineManager().getEngineByName("JavaScript");
        formula = formula.replaceAll("\\{0\\}", value);
        Double result = null;
        try {
            result = (Double) jse.eval(formula);
        } catch (ScriptException e) {
            e.printStackTrace();
        }
        //保留小数点后三位
        BigDecimal bg = new BigDecimal(result);
        result = bg.setScale(num, BigDecimal.ROUND_HALF_UP).doubleValue();
        return result.toString();
    }
}
screen-common/src/main/java/com/moral/util/UnitConvertUtils.java
File was deleted