Bladeren bron

新增细则规则校验

zhangchenglong 2 jaren geleden
bovenliggende
commit
4208c53cbb

+ 2 - 1
src/main/java/com/syjy/calculate/repository/CalculationFormulaRepository.java

@@ -20,6 +20,7 @@ public interface CalculationFormulaRepository {
      * @param type 类型
      * @return 返回记录
      */
-    List<CalculationFormula> findByTypeAndProvince(String type, String provinceEnum);
+    List<CalculationFormula> findByTypeAndProvince(String type, String provinceEnum,String rules);
+
 
 }

+ 6 - 4
src/main/java/com/syjy/calculate/repository/repositoryImpl/CalculationFormulaRepositoryImpl.java

@@ -89,20 +89,22 @@ public class CalculationFormulaRepositoryImpl implements CalculationFormulaRepos
      * @return
      */
     @Override
-    public List<CalculationFormula> findByTypeAndProvince(String type, String provinceEnum) {
+    public List<CalculationFormula> findByTypeAndProvince(String type, String provinceEnum,String rules) {
         // 模糊查询参数
         provinceEnum = "%" + provinceEnum + ";%";
         // 查询sql
         String sql = "SELECT * from t_calculation_formula where TYPE = ? and PROVINCE_ENUM like ?  ";
+        if (!"".equals(rules) && rules != null) {
+            rules = "%" + rules + ";%";
+            sql = "SELECT * from t_calculation_formula where TYPE = ? and PROVINCE_ENUM like ? and RULE_FORMULA like ?";
+        }
         // 根据类型和省调查询公式
         List<CalculationFormula> calculationFormulaList = new ArrayList<>();
         try {
-            calculationFormulaList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(CalculationFormula.class), type, provinceEnum);
+            calculationFormulaList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(CalculationFormula.class), type, provinceEnum,rules);
         } catch (DataAccessException e) {
             e.printStackTrace();
         }
         return calculationFormulaList;
     }
-
-
 }

+ 73 - 28
src/main/java/com/syjy/calculate/service/AccuracyPassRateCalculateService.java

@@ -8,9 +8,7 @@ import com.syjy.calculate.repository.CalculationFormulaRepository;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
-
 import java.math.BigDecimal;
-import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -37,19 +35,28 @@ public class AccuracyPassRateCalculateService {
      * @param provinceEnum 省调
      * @param type         短期、超短期
      * @param compare      通过率对比系数
-     * @return 返回Json  result:fail/success  value: 99%  msg:失败及原因
+     * @return 返回Json  result: true/false  value: 99%  msg:失败及原因
      */
     public JSONObject calculate(JSONArray powerData, BigDecimal rl, String provinceEnum, String type, BigDecimal compare) {
         JSONObject jsonResult = new JSONObject();
         jsonResult.put("result", false);
-        // 获取公式
-        List<CalculationFormula> calculationFormulaList = getCalculationFormulaData(type, provinceEnum);
+        // 对细则进行校验
+        JSONObject checkedJson = checkDataRules(powerData, rl, provinceEnum, type);
+        // 如果细则校验失败,返回细则结果
+        if ("fail".equals(checkedJson.getString("result"))) {
+            jsonResult.put("msg",checkedJson.getString("msg"));
+            return jsonResult;
+        }
+        // 获取细则校验过的数据
+        JSONArray checkedPowerData = checkedJson.getJSONArray("powerData");
+        // 根据类型从数据库中查出公式列表
+        List<CalculationFormula> calculationFormulaList = calculationFormulaRepository.findByTypeAndProvince(type, provinceEnum, null);
         if (calculationFormulaList == null || calculationFormulaList.size() == 0) {
             jsonResult.put("msg", "计算失败,未匹配到公式");
             return jsonResult;
         }
         // 获取功率个数
-        BigDecimal count = BigDecimal.valueOf(powerData.size());
+        BigDecimal count = BigDecimal.valueOf(checkedPowerData.size());
         // 存放每步计算结果
         Map<String, Object> resultMap = new HashMap<>();
         // 公式
@@ -64,8 +71,8 @@ public class AccuracyPassRateCalculateService {
                 // 获取sum后面的公式
                 formula = formula.split(":")[1];
                 // 循环执行sum后的公式
-                for (int i = 0; i < powerData.size(); i++) {
-                    JSONObject dataJson = powerData.getJSONObject(i);
+                for (int i = 0; i < checkedPowerData.size(); i++) {
+                    JSONObject dataJson = checkedPowerData.getJSONObject(i);
                     // 将执行过的公式结果放入dataMap
                     dataJson.putAll(resultMap);
                     dataJson.put("rl", rl);
@@ -97,9 +104,9 @@ public class AccuracyPassRateCalculateService {
                 }
                 // 非求和计算
             } else {
-                if (powerData.size() > 0) {
+                if (checkedPowerData.size() > 0) {
                     // 获取数据测试
-                    JSONObject dataJson = powerData.getJSONObject(0);
+                    JSONObject dataJson = checkedPowerData.getJSONObject(0);
                     // 将执行过的公式结果放入dataMap
                     dataJson.putAll(resultMap);
                     dataJson.put("rl", rl);
@@ -138,39 +145,77 @@ public class AccuracyPassRateCalculateService {
     }
 
     /**
-     * 获取当前省调的公式列表
-     *
-     * @param type         类型
-     * @param provinceEnum 省调(在数据库中省调存储必须带分号,例如:E12;)
-     * @return
-     */
-    public List<CalculationFormula> getCalculationFormulaData(String type, String provinceEnum) {
-        List<CalculationFormula> calculationFormulaList = new ArrayList<>();
-        // 根据类型从数据库中查出公式列表
-        calculationFormulaList = calculationFormulaRepository.findByTypeAndProvince(type, provinceEnum);
-        return calculationFormulaList;
-    }
-
-    /**
      * 过滤结果 <0=0  >100=100
      *
      * @param result 过滤前的结果
      * @return 过滤后的结果
      */
-    private BigDecimal filterResult(BigDecimal result) {
+    public BigDecimal filterResult(BigDecimal result) {
         //当结果为负数时,说明偏差过大,准确率为0
         if (result.compareTo(BigDecimal.ZERO) == -1 || result.compareTo(BigDecimal.ZERO) == 0) {
             result = BigDecimal.ZERO;
         }
-
+        // 如果结果大于1,则准确率设为100
         if (result.compareTo(this.HUNDRED) == 1) {
             result = this.HUNDRED;
         }
         return result;
     }
 
-
-
+    /**
+     * 根据细则过滤数据
+     *
+     * @param powerData
+     * @param rl
+     * @param provinceEnum
+     * @param type
+     * @return
+     */
+    public JSONObject checkDataRules(JSONArray powerData, BigDecimal rl, String provinceEnum, String type) {
+        JSONObject result = new JSONObject();
+        result.put("result", "fail");
+        // 获取细则公式
+        List<CalculationFormula> rulesCalculationFormulaList = calculationFormulaRepository.findByTypeAndProvince(type, provinceEnum, null);
+        // 如果没有细则公式,则不进行细则校验
+        if (rulesCalculationFormulaList == null || rulesCalculationFormulaList.size() == 0) {
+            result.put("result", "success");
+            result.put("powerData", powerData);
+            return result;
+        }
+        JSONArray checkedArray = new JSONArray();
+        JSONObject data = new JSONObject();
+        String checkResult = "";
+        // 循环功率信息
+        for (int i = 0; i < powerData.size(); i++) {
+            String checkFlag = "success";
+            data = powerData.getJSONObject(i);
+            // 循环公式,对每条功率信息进行细则处理
+            for (CalculationFormula formula : rulesCalculationFormulaList) {
+                try {
+                    checkResult = String.valueOf(AviatorEvaluator.execute(formula.getFormula(), data));
+                    if (!"pass".equals(checkResult)) {
+                        checkFlag = "fail";
+                        break;
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    log.error("计算公式:" + formula + "错误:" + e.toString());
+                    return result;
+                }
+            }
+            // 如果循环所有规则后还是success,则此条数据校验通过,放入list中
+            if ("success".equals(checkFlag)) {
+                checkedArray.add(data);
+                // 如果没通过,且为单点数据,则返回细则结果
+            } else if (powerData.size() == 1) {
+                result.put("msg", checkResult);
+                return result;
+            }
+        }
+        result.put("result", "success");
+        result.put("powerData", checkedArray);
+        return result;
+    }
 
 }
 

+ 22 - 21
src/main/resources/sql/t_calculation_formula.sql

@@ -11,7 +11,7 @@
  Target Server Version : 80029
  File Encoding         : 65001
 
- Date: 19/08/2022 15:19:31
+ Date: 30/08/2022 15:11:47
 */
 
 SET NAMES utf8mb4;
@@ -27,6 +27,7 @@ CREATE TABLE `t_calculation_formula`  (
   `ORDER` int(0) NULL DEFAULT NULL COMMENT '公式执行顺讯',
   `FORMULA` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '公式内容',
   `PROVINCE_ENUM` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '省调',
+  `RULE_FORMULA` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '细则对应的公式',
   `STATE` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '状态: 0 失效    1 有效',
   `CREATE_TIME` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
   `CREATOR` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '创建人',
@@ -38,25 +39,25 @@ CREATE TABLE `t_calculation_formula`  (
 -- ----------------------------
 -- Records of t_calculation_formula
 -- ----------------------------
-INSERT INTO `t_calculation_formula` VALUES (1, 'POINT_S', 1, '(1-math.abs((sj-yc)/yc))*100', 'E21Old;E61;E62;E63;E64;', NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `t_calculation_formula` VALUES (2, 'POINT_U', 1, 'sum:math.abs(sj-yc)', 'E61;E62;E63;E64;', NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `t_calculation_formula` VALUES (3, 'POINT_U', 2, 'sum:math.abs((sj/(sj+yc))-0.5)*(math.abs(sj-yc)/result1)', 'E61;E62;E63;E64;', NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `t_calculation_formula` VALUES (4, 'POINT_U', 3, '(1-(2*result2))*100', 'E61;E62;E63;E64;', NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `t_calculation_formula` VALUES (5, 'MAE', 1, 'sum:math.abs(sj-yc)', 'E14;E36;E42;E43;E51;', NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `t_calculation_formula` VALUES (6, 'MAE', 2, '(1-(result1/(rl*count)))*100', 'E14;E36;E42;E43;E51;', NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `t_calculation_formula` VALUES (7, 'MAE_R', 1, 'sum:math.abs((sj-yc)/yc)', 'E21Old;', NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `t_calculation_formula` VALUES (8, 'MAE_R', 2, '(1-(result1/count))*100', 'E21Old;', NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `t_calculation_formula` VALUES (9, 'RMSE_A', 1, 'sum:math.abs(sj-yc)', 'E12;E13;E17;E99;', NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `t_calculation_formula` VALUES (10, 'RMSE_A', 2, 'sum:math.pow((sj-yc),2)*math.abs(sj-yc)/result1', 'E12;E13;E17;E99;', NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `t_calculation_formula` VALUES (11, 'RMSE_A', 3, '(1-(math.sqrt(result2)/rl))*100', 'E12;E13;E17;E99;', NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `t_calculation_formula` VALUES (12, 'RMSE_C', 1, 'sum:math.pow((sj-yc)/rl,2)', 'E15;E21;E22;E23;E23Old;E41;', NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `t_calculation_formula` VALUES (13, 'RMSE_C', 2, '(1-math.sqrt((result1/count)))*100', 'E15;E21;E22;E23;E23Old;E41;', NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `t_calculation_formula` VALUES (14, 'RMSE_R', 1, 'sum:math.pow((sj-yc)/sj,2)', 'E32;E33;E34;', NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `t_calculation_formula` VALUES (15, 'RMSE_R', 2, '(1-math.sqrt((result1/count)))*100', 'E32;E33;E34;', NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `t_calculation_formula` VALUES (16, 'RMSE_S', 1, 'sum:math.pow((sj-yc),2)', 'E22;E23;E36;E37;E42;E43;E44;E45;E51;E62;', NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `t_calculation_formula` VALUES (17, 'RMSE_S', 2, '(1-(math.sqrt(result1)/rl*math.sqrt(count)))*100', 'E22;E23;E36;E37;E42;E43;E44;E45;E51;E62;', NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `t_calculation_formula` VALUES (18, 'PASS', 1, 'sum:(1-math.abs((sj-yc)/rl))*100', 'E14;E15;E21;E22;E23;E23Old;E61;', NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `t_calculation_formula` VALUES (19, 'PASS', 2, 'result1/count', 'E14;E15;E21;E22;E23;E23Old;E61;', NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `t_calculation_formula` VALUES (1, 'POINT_S', 1, '(1-math.abs((sj-yc)/yc))*100', 'E21Old;E61;E62;E63;E64;', NULL, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `t_calculation_formula` VALUES (2, 'POINT_U', 1, 'sum:math.abs(sj-yc)', 'E61;E62;E63;E64;', NULL, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `t_calculation_formula` VALUES (3, 'POINT_U', 2, 'sum:math.abs((sj/(sj+yc))-0.5)*(math.abs(sj-yc)/result1)', 'E61;E62;E63;E64;', NULL, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `t_calculation_formula` VALUES (4, 'POINT_U', 3, '(1-(2*result2))*100', 'E61;E62;E63;E64;', NULL, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `t_calculation_formula` VALUES (5, 'MAE', 1, 'sum:math.abs(sj-yc)', 'E14;E36;E42;E43;E51;', NULL, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `t_calculation_formula` VALUES (6, 'MAE', 2, '(1-(result1/(rl*count)))*100', 'E14;E36;E42;E43;E51;', NULL, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `t_calculation_formula` VALUES (7, 'MAE_R', 1, 'sum:math.abs((sj-yc)/yc)', 'E21Old;', NULL, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `t_calculation_formula` VALUES (8, 'MAE_R', 2, '(1-(result1/count))*100', 'E21Old;', NULL, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `t_calculation_formula` VALUES (9, 'RMSE_A', 1, 'sum:math.abs(sj-yc)', 'E12;E13;E17;E99;', NULL, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `t_calculation_formula` VALUES (10, 'RMSE_A', 2, 'sum:math.pow((sj-yc),2)*math.abs(sj-yc)/result1', 'E12;E13;E17;E99;', NULL, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `t_calculation_formula` VALUES (11, 'RMSE_A', 3, '(1-(math.sqrt(result2)/rl))*100', 'E12;E13;E17;E99;', NULL, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `t_calculation_formula` VALUES (12, 'RMSE_C', 1, 'sum:math.pow((sj-yc)/rl,2)', 'E15;E21;E22;E23;E23Old;E41;', NULL, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `t_calculation_formula` VALUES (13, 'RMSE_C', 2, '(1-math.sqrt((result1/count)))*100', 'E15;E21;E22;E23;E23Old;E41;', NULL, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `t_calculation_formula` VALUES (14, 'RMSE_R', 1, 'sum:math.pow((sj-yc)/sj,2)', 'E32;E33;E34;', NULL, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `t_calculation_formula` VALUES (15, 'RMSE_R', 2, '(1-math.sqrt((result1/count)))*100', 'E32;E33;E34;', NULL, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `t_calculation_formula` VALUES (16, 'RMSE_S', 1, 'sum:math.pow((sj-yc),2)', 'E22;E23;E36;E37;E42;E43;E44;E45;E51;E62;', NULL, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `t_calculation_formula` VALUES (17, 'RMSE_S', 2, '(1-(math.sqrt(result1)/rl*math.sqrt(count)))*100', 'E22;E23;E36;E37;E42;E43;E44;E45;E51;E62;', NULL, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `t_calculation_formula` VALUES (18, 'PASS', 1, 'sum:(1-math.abs((sj-yc)/rl))*100', 'E14;E15;E21;E22;E23;E23Old;E61;', NULL, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `t_calculation_formula` VALUES (19, 'PASS', 2, 'result1/count', 'E14;E15;E21;E22;E23;E23Old;E61;', NULL, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `t_calculation_formula` VALUES (20, 'RULES', 1, 'IF(yc=0,IF(sj<=rl*0.03,\'不予考核\',\'0%\'),IF(sj=0,IF(YC<=rl*0.03,\'不予考核\',\'0%\'),\'pass\'))', 'E61;', 'POINT_S;', NULL, NULL, NULL, NULL, NULL);
 
 SET FOREIGN_KEY_CHECKS = 1;
-