Browse Source

根据两个细则修改南网实际、可用、预测均小于容量10%时,返回结果无数据改为不予考核,修该原方法取到第1个小于10%结果时直接退出后续计算,改为筛掉数据

jyyw 10 tháng trước cách đây
mục cha
commit
8f29ae8c4d

+ 32 - 32
pom.xml

@@ -10,8 +10,8 @@
     </parent>
     <groupId>com.syjy</groupId>
     <artifactId>calculation-spring-boot-starter</artifactId>
-    <version>0.0.34</version>
-<!--    <version>0.0.34-SNAPSHOT</version>-->
+    <version>0.0.35</version>
+    <!--    <version>0.0.35-SNAPSHOT</version>-->
     <name>calculation</name>
     <description>Demo project for Spring Boot</description>
     <properties>
@@ -42,19 +42,19 @@
         </dependency>
 
         <!--本地使用时候放开-->
-<!--        <dependency>-->
-<!--            <groupId>com.alibaba.cloud</groupId>-->
-<!--            <version>2.2.0.RELEASE</version>-->
-<!--            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>-->
-<!--        </dependency>-->
-
-        <!--发布时候放开-->
         <dependency>
-            <groupId>com.alibaba.cloud</groupId>
-            <version>2.2.0.RELEASE</version>
-            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+            <groupId>kingbasejdbc4</groupId>
+            <artifactId>kingbasejdbc4</artifactId>
+            <version>1</version>
         </dependency>
 
+        <!-- 发布时候放开-->
+        <!--        <dependency>-->
+        <!--            <groupId>com.alibaba.cloud</groupId>-->
+        <!--            <version>2.2.0.RELEASE</version>-->
+        <!--            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>-->
+        <!--        </dependency>-->
+
         <!-- druid 连接池 -->
         <dependency>
             <groupId>com.alibaba</groupId>
@@ -124,27 +124,27 @@
 
     <distributionManagement>
 
-<!--        <repository>-->
-<!--            <id>jiayue-releases</id>-->
-<!--            <name>Nexus Release Repository</name>-->
-<!--            <url>http://49.4.68.219:8888/repository/jiayue-releases/</url>-->
-<!--        </repository>-->
-<!--        <snapshotRepository>-->
-<!--            <id>jiayue-snapshots</id>-->
-<!--            <name>Nexus Snapshot Repository</name>-->
-<!--            <url>http://49.4.68.219:8888/repository/jiayue-snapshots/</url>-->
-<!--        </snapshotRepository>-->
-
-        <!--csc-->
         <repository>
-            <id>jiayue-csc-releases</id>
-            <url>http://49.4.68.219:8888/repository/jiayue-csc-releases/</url>
+            <id>jiayue-releases</id>
+            <name>Nexus Release Repository</name>
+            <url>http://49.4.68.219:8888/repository/jiayue-releases/</url>
         </repository>
         <snapshotRepository>
-            <id>jiayue-csc-snapshots</id>
-            <url>http://49.4.68.219:8888/repository/jiayue-csc-snapshots/</url>
+            <id>jiayue-snapshots</id>
+            <name>Nexus Snapshot Repository</name>
+            <url>http://49.4.68.219:8888/repository/jiayue-snapshots/</url>
         </snapshotRepository>
 
+        <!--csc-->
+        <!--        <repository>-->
+        <!--            <id>jiayue-csc-releases</id>-->
+        <!--            <url>http://49.4.68.219:8888/repository/jiayue-csc-releases/</url>-->
+        <!--        </repository>-->
+        <!--        <snapshotRepository>-->
+        <!--            <id>jiayue-csc-snapshots</id>-->
+        <!--            <url>http://49.4.68.219:8888/repository/jiayue-csc-snapshots/</url>-->
+        <!--        </snapshotRepository>-->
+
     </distributionManagement>
 
     <build>
@@ -153,10 +153,10 @@
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-maven-plugin</artifactId>
                 <!--独立打包作为服务和对外接口时候需要注释掉-->
-                <configuration>
-                    <skip>true</skip>
-                    <mainClass>com.syjy.calculate.CalculationApplication</mainClass>
-                </configuration>
+                <!--                <configuration>-->
+                <!--                    <skip>true</skip>-->
+                <!--                    <mainClass>com.syjy.calculate.CalculationApplication</mainClass>-->
+                <!--                </configuration>-->
                 <executions>
                     <execution>
                         <goals>

+ 2 - 2
src/main/java/com/syjy/calculate/conotroller/testCalculate.java

@@ -45,8 +45,8 @@ public class testCalculate {
         calculateRequest.setFormulaType("DAY_SHORT_ACCURACY");
         calculateRequest.setProvince("E45");
         calculateRequest.setElectricType("E2");
-        calculateRequest.setStationCode("J00108");
-        calculateRequest.setElectricCapacity(new BigDecimal("49.1"));
+        calculateRequest.setStationCode("J00377");
+        calculateRequest.setElectricCapacity(new BigDecimal("96.4"));
 
         show = "公式:"+calculateRequest.getFormulaType()+ "</br>省份:"+calculateRequest.getProvince()+"</br>风光:"+ calculateRequest.getElectricType()+"</br>容量:"+calculateRequest.getElectricCapacity()+"</br>";
 

+ 328 - 312
src/main/java/com/syjy/calculate/service/AccuracyPassRateCalculateService.java

@@ -1,14 +1,21 @@
 package com.syjy.calculate.service;
 
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.googlecode.aviator.AviatorEvaluator;
-import com.syjy.calculate.entity.*;
+import com.syjy.calculate.entity.CalculateRequest;
+import com.syjy.calculate.entity.CalculateResult;
+import com.syjy.calculate.entity.CalculationFormula;
+import com.syjy.calculate.entity.CalculationInfo;
 import com.syjy.calculate.repository.CalculationFormulaRepository;
 import com.syjy.calculate.util.Common;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.cglib.beans.BeanMap;
 import org.springframework.stereotype.Service;
+
 import java.math.BigDecimal;
 import java.text.SimpleDateFormat;
 import java.util.*;
@@ -25,347 +32,356 @@ import java.util.stream.Collectors;
 @Slf4j
 public class AccuracyPassRateCalculateService {
 
-    @Autowired
-    private CalculationFormulaRepository calculationFormulaRepository;
-    @Autowired
-    private Common common;
-
-    /**
-     * 计算准确率、合格率
-     *
-     * @param calculateRequest
-     * @return
-     */
-    public CalculateResult calculate(CalculateRequest calculateRequest) {
-        // 根据类型从数据库中查出公式列表
-        CalculationFormula calculationFormula = calculationFormulaRepository.findByTypeAndProvince(CalculateResult.FORMULA, calculateRequest.getFormulaType(), calculateRequest.getProvince(), calculateRequest.getElectricType(), calculateRequest.getStationCode());
-        if (calculationFormula == null || calculationFormula.getFormula() == null) {
-            // 未匹配到公式
-            return CalculateResult.error(CalculateResult.MSG_NO_FORMULA);
-        }
+  @Autowired
+  private CalculationFormulaRepository calculationFormulaRepository;
+  @Autowired
+  private Common common;
 
-        // 对细则进行校验
-        CalculateResult checkedDataResult = checkDataRules(calculateRequest, calculationFormula);
-        // 如果细则校验失败,返回细则结果
-        if (!String.valueOf(checkedDataResult.get(CalculateResult.CODE_TAG)).equals(CalculateResult.Type.SUCCESS.value())) {
-            return checkedDataResult;
-        }
-        // 获取细则校验过的数据
-        List<Map<String, Object>> checkedData = (List<Map<String, Object>>) checkedDataResult.get(CalculateResult.DATA_TAG);
-        if (checkedData == null || checkedData.size() == 0) {
-            return CalculateResult.error(CalculateResult.MSG_CALCULATE_DATA_NULL);
-        }
+  /**
+   * 计算准确率、合格率
+   *
+   * @param calculateRequest
+   * @return
+   */
+  public CalculateResult calculate(CalculateRequest calculateRequest) {
+    // 根据类型从数据库中查出公式列表
+    CalculationFormula calculationFormula = calculationFormulaRepository.findByTypeAndProvince(CalculateResult.FORMULA, calculateRequest.getFormulaType(), calculateRequest.getProvince(), calculateRequest.getElectricType(), calculateRequest.getStationCode());
+    if (calculationFormula == null || calculationFormula.getFormula() == null) {
+      // 未匹配到公式
+      return CalculateResult.error(CalculateResult.MSG_NO_FORMULA);
+    }
 
-        // 获取公式
-        String formula = calculationFormula.getFormula();
-        // 初始化公式并获取缓存的公式
-        String scriptName = common.initFormula(formula, calculateRequest.getProvince(), calculateRequest.getFormulaType(), calculateRequest.getElectricType(), CalculateResult.FORMULA);
-        // 上下文
-        Map<String, Object> env = new HashMap<>();
-        // 如果是多日多文件计算准确率,则将数据根据日期和文件类型分组,并放入list中
-        if (calculationFormula.getDataSourceType() != null) {
-            List<List<Map<String, Object>>> groupingList = groupingList(checkedData, calculationFormula.getDataSourceType());
-            env.put(CalculateResult.LIST, groupingList);
-            if (groupingList == null || groupingList.size() == 0) {
-                return CalculateResult.error(CalculateResult.MSG_CALCULATE_DATA_NULL);
-            }
-            // 如果是多日数据,将数据按照日期分组
-        } else if(calculationFormula.getFormula().contains("manyDay")){
-            List<List<Map<String, Object>>> manyDaysList = groupingDaysList(checkedData,"genTime");
-            env.put(CalculateResult.LIST, manyDaysList);
-        }else {
-            env.put(CalculateResult.LIST, checkedData);
-        }
+    // 对细则进行校验
+    CalculateResult checkedDataResult = checkDataRules(calculateRequest, calculationFormula);
+    // 如果细则校验失败,返回细则结果
+    if (!String.valueOf(checkedDataResult.get(CalculateResult.CODE_TAG)).equals(CalculateResult.Type.SUCCESS.value())) {
+      return checkedDataResult;
+    }
+    // 获取细则校验过的数据
+    List<Map<String, Object>> checkedData = (List<Map<String, Object>>) checkedDataResult.get(CalculateResult.DATA_TAG);
+    if (checkedData == null || checkedData.size() == 0) {
+      return CalculateResult.error(CalculateResult.MSG_CALCULATE_DATA_NULL);
+    }
 
-        // 将需要计算的list数据放入上下文
-        env.put(CalculateResult.CAPACITY, calculateRequest.getElectricCapacity());
-        env.put(CalculateResult.SIGN, calculateRequest.getSign());
-
-        // 获取最大开机容量
-        List<CalculationInfo> calculationInfoList = calculateRequest.getCalculationInfoList();
-        BigDecimal maxOpenCapacity = calculateRequest.getElectricCapacity();
-        // 如果数据不为空,获取最大开机容量
-        if (calculationInfoList != null && calculationInfoList.size() > 0) {
-            calculationInfoList.sort(Comparator.comparing(CalculationInfo::getOpenCapacity).reversed());
-            maxOpenCapacity = calculationInfoList.get(0).getOpenCapacity();
-        }
-        env.put(CalculateResult.MAX_OPEN_CAPACITY, maxOpenCapacity);
-
-        // 执行计算并得出结果
-        try {
-            // 获取计算结果
-            Object executeResult = AviatorEvaluator.getInstance().getCachedExpressionByKey(scriptName).execute(env);
-            // 过滤计算结果
-            String result = filterResult(executeResult, calculationFormula.getIsRate(),calculationFormula.getMaxMinLimit());
-            return CalculateResult.success(CalculateResult.MSG_CALCULATE_SUCCESS, result);
-        } catch (Exception e) {
-            e.printStackTrace();
-            return CalculateResult.error(CalculateResult.MSG_CALCULATE_FAIL + e.toString());
-        }
+    // 获取公式
+    String formula = calculationFormula.getFormula();
+    // 初始化公式并获取缓存的公式
+    String scriptName = common.initFormula(formula, calculateRequest.getProvince(), calculateRequest.getFormulaType(), calculateRequest.getElectricType(), CalculateResult.FORMULA);
+    // 上下文
+    Map<String, Object> env = new HashMap<>();
+    // 如果是多日多文件计算准确率,则将数据根据日期和文件类型分组,并放入list中
+    if (calculationFormula.getDataSourceType() != null) {
+      List<List<Map<String, Object>>> groupingList = groupingList(checkedData, calculationFormula.getDataSourceType());
+      env.put(CalculateResult.LIST, groupingList);
+      if (groupingList == null || groupingList.size() == 0) {
+        return CalculateResult.error(CalculateResult.MSG_CALCULATE_DATA_NULL);
+      }
+      // 如果是多日数据,将数据按照日期分组
+    } else if (calculationFormula.getFormula().contains("manyDay")) {
+      List<List<Map<String, Object>>> manyDaysList = groupingDaysList(checkedData, "genTime");
+      env.put(CalculateResult.LIST, manyDaysList);
+    } else {
+      env.put(CalculateResult.LIST, checkedData);
     }
 
-    /**
-     * 过滤结果 <0=0  >100=100
-     *
-     * @param result 过滤前的结果
-     * @return 过滤后的结果
-     */
-    private String filterResult(Object result, String type ,String maxMinLimit) {
-        // 如果是map类型,转为jsonString
-        if (result instanceof HashMap) {
-            String jsonStr = JSONObject.toJSONString(result);
-            return jsonStr;
-        }
-        // 如果返回的不是数值类型,则不用过滤,直接返回
-        if ((result instanceof String) || (result instanceof Boolean) || (result instanceof HashMap)) {
-            return String.valueOf(result);
-        }
-        BigDecimal resultBig = new BigDecimal(String.valueOf(result));
-        // 判断计算结果是否限定上下限
-        if(maxMinLimit != null && maxMinLimit.equals(CalculateResult.STR_TRUE)){
-            //当结果为负数时,说明偏差过大,准确率为0
-            if (resultBig.compareTo(BigDecimal.ZERO) == -1 || resultBig.compareTo(BigDecimal.ZERO) == 0) {
-                log.warn("结果为负数:" + resultBig + "自动转换为0%");
-                resultBig = BigDecimal.ZERO;
-            }
-            // 如果结果大于1,则准确率设为100
-            if (resultBig.compareTo(BigDecimal.ONE) == 1) {
-                log.warn("结果大于100%:" + resultBig + "自动转换为100%");
-                resultBig = BigDecimal.ONE;
-            }
-        }
+    // 将需要计算的list数据放入上下文
+    env.put(CalculateResult.CAPACITY, calculateRequest.getElectricCapacity());
+    env.put(CalculateResult.SIGN, calculateRequest.getSign());
 
-        // 如果公式结果为带百分号
-        if (type != null && type.equals(CalculateResult.STR_TRUE)) {
-            // 对数据*100
-            resultBig = resultBig.multiply(CalculateResult.ONE_HUNDRED);
-            // 对数据进行四舍五入
-            resultBig = resultBig.setScale(2, BigDecimal.ROUND_HALF_UP);
-            // 数据加上百分号
-            return resultBig + CalculateResult.PERCENT;
-        }
+    // 获取最大开机容量
+    List<CalculationInfo> calculationInfoList = calculateRequest.getCalculationInfoList();
+    BigDecimal maxOpenCapacity = calculateRequest.getElectricCapacity();
+    // 如果数据不为空,获取最大开机容量
+    if (calculationInfoList != null && calculationInfoList.size() > 0) {
+      calculationInfoList.sort(Comparator.comparing(CalculationInfo::getOpenCapacity).reversed());
+      maxOpenCapacity = calculationInfoList.get(0).getOpenCapacity();
+    }
+    env.put(CalculateResult.MAX_OPEN_CAPACITY, maxOpenCapacity);
 
-        //如果结果不带百分号,直接四舍五入4位小数
-        resultBig = resultBig.setScale(4, BigDecimal.ROUND_HALF_UP);
+    // 执行计算并得出结果
+    try {
+      // 获取计算结果
+      Object executeResult = AviatorEvaluator.getInstance().getCachedExpressionByKey(scriptName).execute(env);
+      // 过滤计算结果
+      String result = filterResult(executeResult, calculationFormula.getIsRate(), calculationFormula.getMaxMinLimit());
+      return CalculateResult.success(CalculateResult.MSG_CALCULATE_SUCCESS, result);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return CalculateResult.error(CalculateResult.MSG_CALCULATE_FAIL + e.toString());
+    }
+  }
 
-        return resultBig.toString();
+  /**
+   * 过滤结果 <0=0  >100=100
+   *
+   * @param result 过滤前的结果
+   * @return 过滤后的结果
+   */
+  private String filterResult(Object result, String type, String maxMinLimit) {
+    // 如果是map类型,转为jsonString
+    if (result instanceof HashMap) {
+      String jsonStr = JSONObject.toJSONString(result);
+      return jsonStr;
+    }
+    // 如果返回的不是数值类型,则不用过滤,直接返回
+    if ((result instanceof String) || (result instanceof Boolean) || (result instanceof HashMap)) {
+      return String.valueOf(result);
+    }
+    BigDecimal resultBig = new BigDecimal(String.valueOf(result));
+    // 判断计算结果是否限定上下限
+    if (maxMinLimit != null && maxMinLimit.equals(CalculateResult.STR_TRUE)) {
+      //当结果为负数时,说明偏差过大,准确率为0
+      if (resultBig.compareTo(BigDecimal.ZERO) == -1 || resultBig.compareTo(BigDecimal.ZERO) == 0) {
+        log.warn("结果为负数:" + resultBig + "自动转换为0%");
+        resultBig = BigDecimal.ZERO;
+      }
+      // 如果结果大于1,则准确率设为100
+      if (resultBig.compareTo(BigDecimal.ONE) == 1) {
+        log.warn("结果大于100%:" + resultBig + "自动转换为100%");
+        resultBig = BigDecimal.ONE;
+      }
     }
 
-    /**
-     * 根据细则过滤数据
-     *
-     * @param calculateRequest
-     * @param calculateRequest
-     * @return
-     */
-    private CalculateResult checkDataRules(CalculateRequest calculateRequest, CalculationFormula calculationFormula) {
-        // 对入参进行校验
-        if (calculateRequest == null) {
-            return CalculateResult.error(CalculateResult.MSG_REQUEST_NULL);
-        }
-        // 公式类型
-        String formulaType = calculateRequest.getFormulaType();
-        if ("".equals(formulaType) || formulaType == null) {
-            return CalculateResult.error(CalculateResult.MSG_FORMULA_TYPE_NULL);
-        }
-        // 省调
-        String province = calculateRequest.getProvince();
-        if ("".equals(province) || province == null) {
-            return CalculateResult.error(CalculateResult.MSG_PROVINCE_NULL);
-        }
+    // 如果公式结果为带百分号
+    if (type != null && type.equals(CalculateResult.STR_TRUE)) {
+      // 对数据*100
+      resultBig = resultBig.multiply(CalculateResult.ONE_HUNDRED);
+      // 对数据进行四舍五入
+      resultBig = resultBig.setScale(2, BigDecimal.ROUND_HALF_UP);
+      // 数据加上百分号
+      return resultBig + CalculateResult.PERCENT;
+    }
 
-        // 场站编码
-        String stationCode = calculateRequest.getStationCode();
-        if ("".equals(stationCode) || stationCode == null) {
-            return CalculateResult.error(CalculateResult.MSG_STATION_CODE_NULL);
-        }
+    //如果结果不带百分号,直接四舍五入4位小数
+    resultBig = resultBig.setScale(4, BigDecimal.ROUND_HALF_UP);
 
-        // 场站类型
-        String electricType = calculateRequest.getElectricType();
-        if ("".equals(electricType) || electricType == null) {
-            return CalculateResult.error(CalculateResult.MSG_ELECTRIC_TYPE_NULL);
-        }
-        // 获取被校验数据
-        List<CalculationInfo> calculationInfoList = calculateRequest.getCalculationInfoList();
+    return resultBig.toString();
+  }
 
-        // 计算数据为空
-        if (calculationInfoList == null || calculationInfoList.size() == 0) {
-            return CalculateResult.error(CalculateResult.MSG_CALCULATE_DATA_NULL);
-        }
+  /**
+   * 根据细则过滤数据
+   *
+   * @param calculateRequest
+   * @param calculateRequest
+   * @return
+   */
+  private CalculateResult checkDataRules(CalculateRequest calculateRequest, CalculationFormula calculationFormula) {
+    // 对入参进行校验
+    if (calculateRequest == null) {
+      return CalculateResult.error(CalculateResult.MSG_REQUEST_NULL);
+    }
+    // 公式类型
+    String formulaType = calculateRequest.getFormulaType();
+    if ("".equals(formulaType) || formulaType == null) {
+      return CalculateResult.error(CalculateResult.MSG_FORMULA_TYPE_NULL);
+    }
+    // 省调
+    String province = calculateRequest.getProvince();
+    if ("".equals(province) || province == null) {
+      return CalculateResult.error(CalculateResult.MSG_PROVINCE_NULL);
+    }
 
-        // 装机容量校验
-        if (calculateRequest.getElectricCapacity() == null || calculateRequest.getElectricCapacity().compareTo(BigDecimal.ZERO) == 0) {
-            return CalculateResult.error(CalculateResult.MSG_CAP_NULL);
-        }
+    // 场站编码
+    String stationCode = calculateRequest.getStationCode();
+    if ("".equals(stationCode) || stationCode == null) {
+      return CalculateResult.error(CalculateResult.MSG_STATION_CODE_NULL);
+    }
 
-        // 获取细则公式
-        CalculationFormula rulesCalculationFormula = calculationFormulaRepository.findByTypeAndProvince(CalculateResult.RULES, formulaType, province, electricType, stationCode);
+    // 场站类型
+    String electricType = calculateRequest.getElectricType();
+    if ("".equals(electricType) || electricType == null) {
+      return CalculateResult.error(CalculateResult.MSG_ELECTRIC_TYPE_NULL);
+    }
+    // 获取被校验数据
+    List<CalculationInfo> calculationInfoList = calculateRequest.getCalculationInfoList();
 
-        // 将数据转为List Map 格式
-        List<Map<String, Object>> calculationInfoListMap = getCalculationInfoList(calculationInfoList, calculateRequest.getElectricCapacity());
+    // 计算数据为空
+    if (calculationInfoList == null || calculationInfoList.size() == 0) {
+      return CalculateResult.error(CalculateResult.MSG_CALCULATE_DATA_NULL);
+    }
 
-        if (rulesCalculationFormula == null || rulesCalculationFormula.getFormula() == null) {
-            // 未匹配到细则文件,则不进行细则校验,返回数据
-            return CalculateResult.success(calculationInfoListMap);
-        }
+    // 装机容量校验
+    if (calculateRequest.getElectricCapacity() == null || calculateRequest.getElectricCapacity().compareTo(BigDecimal.ZERO) == 0) {
+      return CalculateResult.error(CalculateResult.MSG_CAP_NULL);
+    }
 
-        // 获取数据文件类型
-        String dataSourceType = calculationFormula.getDataSourceType();
-        // 获取公式
-        String formulaInfo = calculationFormula.getFormula();
-
-        // 如果 实际功率/可用功率/预测功率为null 则剔除此条
-        calculationInfoList.stream().filter(s -> s.getAbleValue() != null && s.getForecastAbleValue() != null);
-        // 循环判断实际功率/预测功率、开机容量
-        for (int i = 0; i < calculationInfoList.size(); i++) {
-            // 如果公式中包含开机容量,才校验
-            if (formulaInfo.indexOf("openCapacity") > 0) {
-                // 如果开机容量 null 返回
-                if (calculationInfoList.get(i).getOpenCapacity() == null || calculationInfoList.get(i).getOpenCapacity().compareTo(BigDecimal.ZERO) == 0) {
-                    return CalculateResult.error(CalculateResult.MSG_CAP_NULL);
-                }
-            }
-            // 如果数据文件类型不为空,则判断数据的生成时间和文件类型不可以为空
-            if (dataSourceType != null && !"".equals(dataSourceType)) {
-                if (calculationInfoList.get(i).getGenTime() == null) {
-                    return CalculateResult.error(CalculateResult.MSG_GEN_TIME_NULL);
-                }
-                if (calculationInfoList.get(i).getDataSourceType() == null || "".equals(calculationInfoList.get(i).getDataSourceType())) {
-                    return CalculateResult.error(CalculateResult.MSG_DATA_SOURCE_TYPE_NULL);
-                }
-            }
+    // 获取细则公式
+    CalculationFormula rulesCalculationFormula = calculationFormulaRepository.findByTypeAndProvince(CalculateResult.RULES, formulaType, province, electricType, stationCode);
+
+    // 将数据转为List Map 格式
+    List<Map<String, Object>> calculationInfoListMap = getCalculationInfoList(calculationInfoList, calculateRequest.getElectricCapacity());
+
+    if (rulesCalculationFormula == null || rulesCalculationFormula.getFormula() == null) {
+      // 未匹配到细则文件,则不进行细则校验,返回数据
+      return CalculateResult.success(calculationInfoListMap);
+    }
+
+    // 获取数据文件类型
+    String dataSourceType = calculationFormula.getDataSourceType();
+    // 获取公式
+    String formulaInfo = calculationFormula.getFormula();
+
+    // 如果 实际功率/可用功率/预测功率为null 则剔除此条
+    calculationInfoList.stream().filter(s -> s.getAbleValue() != null && s.getForecastAbleValue() != null);
+    // 循环判断实际功率/预测功率、开机容量
+    for (int i = 0; i < calculationInfoList.size(); i++) {
+      // 如果公式中包含开机容量,才校验
+      if (formulaInfo.indexOf("openCapacity") > 0) {
+        // 如果开机容量 null 返回
+        if (calculationInfoList.get(i).getOpenCapacity() == null || calculationInfoList.get(i).getOpenCapacity().compareTo(BigDecimal.ZERO) == 0) {
+          return CalculateResult.error(CalculateResult.MSG_CAP_NULL);
+        }
+      }
+      // 如果数据文件类型不为空,则判断数据的生成时间和文件类型不可以为空
+      if (dataSourceType != null && !"".equals(dataSourceType)) {
+        if (calculationInfoList.get(i).getGenTime() == null) {
+          return CalculateResult.error(CalculateResult.MSG_GEN_TIME_NULL);
         }
+        if (calculationInfoList.get(i).getDataSourceType() == null || "".equals(calculationInfoList.get(i).getDataSourceType())) {
+          return CalculateResult.error(CalculateResult.MSG_DATA_SOURCE_TYPE_NULL);
+        }
+      }
+    }
 
-        // 获取公式
-        String formula = rulesCalculationFormula.getFormula();
-        // 初始化公式并获取缓存的公式
-        String scriptName = common.initFormula(formula, calculateRequest.getProvince(), calculateRequest.getFormulaType(), calculateRequest.getElectricType(), CalculateResult.RULES);
-        // 通过校验的数据
-        List<Map<String, Object>> passList = new ArrayList<>();
-        // 循环数据,对数据进行校验
-        for (Map<String, Object> calculationMap : calculationInfoListMap) {
-            // 循环公式,对每条功率信息进行细则处理
-            try {
-                Map<String, Object> checkResult = (HashMap<String, Object>) AviatorEvaluator.getInstance().getCachedExpressionByKey(scriptName).execute(calculationMap);
-                // 如果返回结果是忽略,则结束本次循环
-                if (String.valueOf(checkResult.get(CalculateResult.CODE_TAG)).equals(CalculateResult.IGNORE)) {
-                    continue;
-
-                    // 如果返回错误,直接返回结果
-                } else if (String.valueOf(checkResult.get(CalculateResult.CODE_TAG)).equals(CalculateResult.ERROR)) {
-                    String resultValue = String.valueOf(checkResult.get(CalculateResult.DATA_TAG));
-                    String msg = String.valueOf(checkResult.get(CalculateResult.MSG_TAG));
-                    return CalculateResult.error(msg, resultValue);
-                }
-                // 校验成功,将通过的数据放入passList
-                passList.add(calculationMap);
-            } catch (Exception e) {
-                log.error(CalculateResult.MSG_DATA_CHECK_ERROR + e.toString());
-                return CalculateResult.error(CalculateResult.MSG_DATA_CHECK_ERROR);
-            }
+    // 获取公式
+    String formula = rulesCalculationFormula.getFormula();
+    // 初始化公式并获取缓存的公式
+    String scriptName = common.initFormula(formula, calculateRequest.getProvince(), calculateRequest.getFormulaType(), calculateRequest.getElectricType(), CalculateResult.RULES);
+    // 通过校验的数据
+    List<Map<String, Object>> passList = new ArrayList<>();
+    List<Map<String, Object>> no_assessment = new ArrayList<>();
+    // 循环数据,对数据进行校验
+    for (Map<String, Object> calculationMap : calculationInfoListMap) {
+      // 循环公式,对每条功率信息进行细则处理
+      try {
+        Map<String, Object> checkResult = Convert.toMap(String.class, Object.class, AviatorEvaluator.getInstance().getCachedExpressionByKey(scriptName).execute(calculationMap));
+        // 如果返回结果是忽略,则结束本次循环
+        if (String.valueOf(checkResult.get(CalculateResult.CODE_TAG)).equals(CalculateResult.IGNORE)) {
+          if (StrUtil.contains(Convert.toStr(checkResult.get(CalculateResult.DATA_TAG), ""), "不予考核")) {
+            no_assessment.add(checkResult);
+          }
+          continue;
+          // 如果返回错误,直接返回结果
+        } else if (String.valueOf(checkResult.get(CalculateResult.CODE_TAG)).equals(CalculateResult.ERROR)) {
+          String resultValue = String.valueOf(checkResult.get(CalculateResult.DATA_TAG));
+          String msg = String.valueOf(checkResult.get(CalculateResult.MSG_TAG));
+          return CalculateResult.error(msg, resultValue);
         }
-        // 校验成功,返回待计算的数据
-        return CalculateResult.success(passList);
+        // 校验成功,将通过的数据放入passList
+        passList.add(calculationMap);
+      } catch (Exception e) {
+        log.error("{}{}", CalculateResult.MSG_DATA_CHECK_ERROR, e.toString());
+        return CalculateResult.error(CalculateResult.MSG_DATA_CHECK_ERROR);
+      }
+    }
+    if (passList.isEmpty() && no_assessment.size() == calculationInfoListMap.size()) {
+      Map<String, Object> checkResult = CollUtil.getLast(no_assessment);
+      String resultValue = String.valueOf(checkResult.get(CalculateResult.DATA_TAG));
+      String msg = String.valueOf(checkResult.get(CalculateResult.MSG_TAG));
+      return CalculateResult.error(msg, resultValue);
     }
+    // 校验成功,返回待计算的数据
+    return CalculateResult.success(passList);
+  }
 
-    /**
-     * 格式化被校验数据
-     *
-     * @return
-     */
-    private List<Map<String, Object>> getCalculationInfoList(List<CalculationInfo> calculationInfoList, BigDecimal electricCapacity) {
-        List<Map<String, Object>> resultList = new ArrayList<>();
-        long time;
-        Date timeDate;
-        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-        // 循环每条数据
-        for (CalculationInfo calculationInfo : calculationInfoList) {
-            // 将bean BeanMap
-            BeanMap beanMap = BeanMap.create(calculationInfo);
-            Map<String, Object> map = new HashMap<>();
-            // 将beanMap转为Map
-            for (Object key : beanMap.keySet()) {
-                map.put(String.valueOf(key), beanMap.get(key));
-                if("time".equals(key.toString())){
-                    time = (long)beanMap.get(key);
-                    timeDate = new Date(time);
-                    map.put("timeStr", sdf.format(timeDate));
-                }
-            }
-            map.put("electricCapacity", electricCapacity);
-            resultList.add(map);
+  /**
+   * 格式化被校验数据
+   *
+   * @return
+   */
+  private List<Map<String, Object>> getCalculationInfoList(List<CalculationInfo> calculationInfoList, BigDecimal electricCapacity) {
+    List<Map<String, Object>> resultList = new ArrayList<>();
+    long time;
+    Date timeDate;
+    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+    // 循环每条数据
+    for (CalculationInfo calculationInfo : calculationInfoList) {
+      // 将bean BeanMap
+      BeanMap beanMap = BeanMap.create(calculationInfo);
+      Map<String, Object> map = new HashMap<>();
+      // 将beanMap转为Map
+      for (Object key : beanMap.keySet()) {
+        map.put(String.valueOf(key), beanMap.get(key));
+        if ("time".equals(key.toString())) {
+          time = (long) beanMap.get(key);
+          timeDate = new Date(time);
+          map.put("timeStr", sdf.format(timeDate));
         }
-        return resultList;
+      }
+      map.put("electricCapacity", electricCapacity);
+      resultList.add(map);
     }
+    return resultList;
+  }
 
-    /**
-     * 将多组计算准确率的数据,分组成每个文件类型为一组,并放入list中
-     *
-     * @param list
-     * @param dataSourceType
-     * @return
-     */
-    private List<List<Map<String, Object>>> groupingList(List<Map<String, Object>> list, String dataSourceType) {
-        // 将文件类型转为arr
-        String[] dataSourceTypeArr = dataSourceType.split(CalculateResult.COMMA);
-        // 最终分好组的list
-        List<List<Map<String, Object>>> groupingList = new ArrayList<>();
-        // 同一个生成时间和同一个文件类型的数据,分再一组
-        List<Map<String, Object>> group = new ArrayList<>();
-        // 对比时间
-        Date dataTime = (Date) list.get(0).get("genTime");
-        for (String type : dataSourceTypeArr) {
-            for (Map<String, Object> map : list) {
-                // 获取数据生成时间
-                Date forDataTime = (Date) map.get("genTime");
-                // 如果当前数据的文件类型是当前循环中的
-                if (map.get("dataSourceType").equals(type)) {
-                    // 如果当前数据和上一条数据的 生成时间相同,则放入组中
-                    if (dataTime.equals(forDataTime)) {
-                        group.add(map);
-                        // 如果不是,则将dataTime修改为新时间,并将之前的组数据放入最终list
-                    } else {
-                        dataTime = forDataTime;
-                        if (group.size() != 0) {
-                            groupingList.add(group);
-                        }
-                        // 清空之前的组,向组中放入本次内循环的数据
-                        group = new ArrayList<>();
-                        group.add(map);
-                    }
-                    // 如果当前数据的文件类型 不是当前循环中的,将之前的组存入最终list,并清空组
-                } else {
-                    if (group.size() != 0) {
-                        groupingList.add(group);
-                    }
-                    group = new ArrayList<>();
-                    continue;
-                }
-            }
-            // 内循环最后一次执行完后,将未保存的组数据存入最终list
+  /**
+   * 将多组计算准确率的数据,分组成每个文件类型为一组,并放入list中
+   *
+   * @param list
+   * @param dataSourceType
+   * @return
+   */
+  private List<List<Map<String, Object>>> groupingList(List<Map<String, Object>> list, String dataSourceType) {
+    // 将文件类型转为arr
+    String[] dataSourceTypeArr = dataSourceType.split(CalculateResult.COMMA);
+    // 最终分好组的list
+    List<List<Map<String, Object>>> groupingList = new ArrayList<>();
+    // 同一个生成时间和同一个文件类型的数据,分再一组
+    List<Map<String, Object>> group = new ArrayList<>();
+    // 对比时间
+    Date dataTime = (Date) list.get(0).get("genTime");
+    for (String type : dataSourceTypeArr) {
+      for (Map<String, Object> map : list) {
+        // 获取数据生成时间
+        Date forDataTime = (Date) map.get("genTime");
+        // 如果当前数据的文件类型是当前循环中的
+        if (map.get("dataSourceType").equals(type)) {
+          // 如果当前数据和上一条数据的 生成时间相同,则放入组中
+          if (dataTime.equals(forDataTime)) {
+            group.add(map);
+            // 如果不是,则将dataTime修改为新时间,并将之前的组数据放入最终list
+          } else {
+            dataTime = forDataTime;
             if (group.size() != 0) {
-                groupingList.add(group);
+              groupingList.add(group);
             }
+            // 清空之前的组,向组中放入本次内循环的数据
+            group = new ArrayList<>();
+            group.add(map);
+          }
+          // 如果当前数据的文件类型 不是当前循环中的,将之前的组存入最终list,并清空组
+        } else {
+          if (group.size() != 0) {
+            groupingList.add(group);
+          }
+          group = new ArrayList<>();
+          continue;
         }
-
-        return groupingList;
+      }
+      // 内循环最后一次执行完后,将未保存的组数据存入最终list
+      if (group.size() != 0) {
+        groupingList.add(group);
+      }
     }
-    /**
-     * 将多日数据分成多组,并放入list中
-     *
-     * @param list
-     * @return
-     */
-    private List<List<Map<String, Object>>> groupingDaysList(List<Map<String, Object>> list,String groupBy) {
-        List<List<Map<String, Object>>> groupingList = new ArrayList<>();
-
-        Map<String, List<Map<String, Object>>> groupedMap = list.stream()
-                .collect(Collectors.groupingBy(map -> map.get(groupBy).toString().substring(0,10)));
-
-        for (Map.Entry<String, List<Map<String, Object>>> entry : groupedMap.entrySet()) {
-            groupingList.add(entry.getValue());
-        }
-        return groupingList;
+
+    return groupingList;
+  }
+
+  /**
+   * 将多日数据分成多组,并放入list中
+   *
+   * @param list
+   * @return
+   */
+  private List<List<Map<String, Object>>> groupingDaysList(List<Map<String, Object>> list, String groupBy) {
+    List<List<Map<String, Object>>> groupingList = new ArrayList<>();
+
+    Map<String, List<Map<String, Object>>> groupedMap = list.stream().collect(Collectors.groupingBy(map -> map.get(groupBy).toString().substring(0, 10)));
+
+    for (Map.Entry<String, List<Map<String, Object>>> entry : groupedMap.entrySet()) {
+      groupingList.add(entry.getValue());
     }
+    return groupingList;
+  }
 }
 

+ 3 - 3
src/main/resources/application.yml

@@ -7,7 +7,7 @@
 #      # 数据源配置
 #      username: root
 #      password: '!QAZ2root'
-#      url: jdbc:mysql://localhost:3306/ipfcst-v3?useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&autoReconnect=true&rewriteBatchedStatements=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai
+#      url: jdbc:mysql://localhost:3306/ipfcst-v3?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&characterSetResults=UTF-8&autoReconnect=true&rewriteBatchedStatements=true&serverTimezone=Asia/Shanghai
 #      driver-class-name: com.mysql.cj.jdbc.Driver
 
 #      金仓数据库
@@ -19,11 +19,11 @@
 #logging:
 #  file:
 #    name: ./logs/calculate.log
-
+#
 #calculate:
 #  service:
 #    enabled: true
-#    version: 0.0.33
+#    version: 0.0.35
 #    dbType: mysql
 
 version: @project.version@

BIN
src/main/resources/sql/t_calculation_formula.xlsx