Browse Source

质检-公式开发
1、监理表获取质检数据公式开发

LHB 2 tuần trước cách đây
mục cha
commit
a3473439f6

+ 3 - 0
blade-service/blade-manager/src/main/java/com/jfireel/expression/parse/impl/NodeParser.java

@@ -23,6 +23,9 @@ public abstract class NodeParser {
     }
 
     protected int skipWhiteSpace(int offset, String el) {
+        int length = el.length();
+        char c = el.charAt(59);
+        char aChar = getChar(offset, el);
         while (CharType.isWhitespace(getChar(offset, el))) {
             offset++;
         }

+ 9 - 2
blade-service/blade-manager/src/main/java/com/jfireel/expression/parse/impl/RightParenParser.java

@@ -2,6 +2,7 @@ package com.jfireel.expression.parse.impl;
 
 import com.jfireel.expression.node.CalculateNode;
 import com.jfireel.expression.node.MethodNode;
+import com.jfireel.expression.node.impl.StringNode;
 import com.jfireel.expression.parse.Invoker;
 import com.jfireel.expression.token.Symbol;
 import com.jfireel.expression.token.Token;
@@ -36,8 +37,14 @@ public class RightParenParser extends NodeParser {
             for (int i = 0; i < list.size(); ) {
                 if (list.get(i).type() == Symbol.COMMA) {
                     list.remove(i);
-                    argsNodes.add(OperatorResultUtil.aggregate(list.subList(0, i), function, el, offset));
-                    list.remove(0);
+                    CalculateNode aggregate = OperatorResultUtil.aggregate(list.subList(0, i), function, el, offset);
+                    if(aggregate != null){
+                        argsNodes.add(aggregate);
+                        list.remove(0);
+                    }else{
+                        argsNodes.add(new StringNode(""));
+                    }
+
                     i = 0;
                 } else {
                     i++;

+ 1 - 1
blade-service/blade-manager/src/main/java/com/jfireel/expression/util/CharType.java

@@ -45,7 +45,7 @@ public class CharType {
      * @return 是否为中文
      */
     public static boolean isChineseChar(final char ch) {
-        return ch >= 0x4E00 && ch <= 0x9FFF || ch >= 0x3400 && ch <= 0x4DBF||ch=='{'||ch=='{';
+        return ch >= 0x4E00 && ch <= 0x9FFF || ch >= 0x3400 && ch <= 0x4DBF||ch=='{'||ch=='{'||ch == '±';
     }
 
 

+ 2 - 1
blade-service/blade-manager/src/main/java/com/jfireel/expression/util/OperatorResultUtil.java

@@ -114,7 +114,8 @@ public class OperatorResultUtil {
             }
             return list.get(0);
         } else {
-            throw new IllegalArgumentException(el.substring(0, offset));
+            return null;
+//            throw new IllegalArgumentException(el.substring(0, offset));
         }
     }
 

+ 47 - 1
blade-service/blade-manager/src/main/java/com/mixsmart/utils/CustomFunction.java

@@ -11,6 +11,7 @@ import com.jfireel.expression.node.impl.VariableNode;
 import com.jfireel.expression.token.Token;
 import org.apache.commons.collections4.MapUtils;
 import org.springblade.common.utils.BaseUtils;
+import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.redis.cache.BladeRedis;
 import org.springblade.core.tool.utils.*;
 import org.springblade.manager.dto.ParamElements;
@@ -3063,6 +3064,51 @@ public class CustomFunction {
     }*/
 
 
+    /**
+     * 数据过滤提取
+     * @param bias 偏差 字符串,例如:±10、+10,-20;
+     * @param designData 设置值,数组,
+     * @param actualData 实测值,数组,
+     * @param biasData 偏差值 数组,
+     */
+    public static Object dataFilterExtract(Object bias,Object biasTwo,Object designData,Object actualData,Object biasData){
+        List<Object> obj1 = new ArrayList<>();
+        List<Object> obj2 = new ArrayList<>();
+        List<Object> obj3 = new ArrayList<>();
+        //返回结果
+        List<Object> result = new ArrayList<>();
 
-
+        if (designData != null) {
+            obj1 = obj2List(designData);
+
+        }
+        if (actualData != null) {
+            obj2 = obj2List(actualData);
+        }
+        if (biasData != null) {
+            obj3 = obj2List(biasData);
+        }
+        //三种数据长度必须一致
+        if(obj1.size() == obj2.size() && obj1.size() == obj3.size()){
+            //满足设置值的索引
+            Map<String, List<Integer>> stringListMap = StringUtils.deduplicateWithIndices(StringUtils.parseDeviationRange(bias, biasTwo),obj1,obj3);
+            List<Object> finalObj = obj2;
+            stringListMap.forEach((key, value) -> {
+                //索引
+                List<Integer> index = stringListMap.get(key);
+                int sampleSize = index.size();
+               //如果样本数量小于5,则获取全部数据
+                if(index.size() > 1){
+                    // 计算需要抽取的元素数量
+                    sampleSize = (int) Math.ceil(index.size() * 0.3);
+                }
+                // 随机打乱列表
+                Collections.shuffle(index);
+                index.stream().limit(sampleSize).forEach(i ->{
+                    result.add(finalObj.get(i));
+                });
+            });
+        }
+        return result;
+    }
 }

+ 111 - 0
blade-service/blade-manager/src/main/java/com/mixsmart/utils/StringUtils.java

@@ -5,7 +5,9 @@ import com.bstek.ureport.console.designer.ReportUtils;
 import com.jfirer.baseutil.encrypt.Md5Util;
 import com.mixsmart.constant.IMixConstant;
 import com.mixsmart.exception.NullArgumentException;
+import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.tool.utils.StringPool;
+import org.springblade.core.tool.utils.StringUtil;
 
 import java.io.UnsupportedEncodingException;
 import java.lang.reflect.Field;
@@ -1428,5 +1430,114 @@ public class StringUtils {
         return f;
     }
 
+    /**
+     * 解析偏差值字符串,返回上下限范围
+     * 支持格式:±10、+10,-20、10,-20、+10、-20 等
+     */
+    public static Range parseDeviationRange(Object obj1, Object obj12) {
+        if(obj1 instanceof List){
+            obj1 = ((List)obj1).get(0);
+        }
+        String deviationStr = String.valueOf(obj1).trim();
+        String biasTwo = String.valueOf(obj12).trim();
+        int target = 0;
+
+        // 处理 ± 格式
+        if (deviationStr.startsWith("±")) {
+            int value = Integer.parseInt(deviationStr.substring(1).trim());
+            return new Range(target - value, target + value);
+        }
+
+        // 处理逗号分隔的格式
+        if (deviationStr.contains(",")) {
+            String[] parts = deviationStr.split(",");
+            if (parts.length == 2) {
+                int upperDev = parseSingleDeviation(parts[0].trim());
+                int lowerDev = parseSingleDeviation(parts[1].trim());
+                if(upperDev > lowerDev){
+                    return new Range(lowerDev, upperDev);
+                }else{
+                    return new Range(upperDev, lowerDev);
+                }
+            }
+        }
+
+        // 处理多个数据的格式
+        if (StringUtil.isNotBlank(deviationStr) && StringUtil.isNotBlank(biasTwo)) {
+            if(deviationStr.contains("+") || biasTwo.contains("+")){
+                deviationStr = deviationStr.replaceAll("\\+", "");
+                biasTwo = biasTwo.replaceAll("\\+","");
+            }
+            if(!StringUtils.isNumber(deviationStr) || !StringUtils.isNumber(biasTwo)){
+                throw new ServiceException(deviationStr + "或" + biasTwo + "----不是数字");
+            }
+            double v = Double.parseDouble(deviationStr);
+            double v1 = Double.parseDouble(biasTwo);
+            if(v > v1){
+                return new Range(v1, v);
+            }else{
+                return new Range(v, v1);
+            }
+        }
+
+        // 处理单个值格式
+        int singleDev = parseSingleDeviation(deviationStr);
+        return new Range(target - singleDev, target + singleDev);
+    }
+    /**
+     * 解析单个偏差值(支持 +10、-20、10 等格式)
+     */
+    private static int parseSingleDeviation(String devStr) {
+        if (devStr.startsWith("+") || devStr.startsWith("-")) {
+            return Integer.parseInt(devStr);
+        } else {
+            return Integer.parseInt(devStr);
+        }
+    }
+    /**
+     * 范围类,存储上下限
+     */
+    public static class Range {
+        public final double lower;
+        public final double upper;
+
+        public Range(double lower, double upper) {
+            this.lower = lower;
+            this.upper = upper;
+        }
+
+        @Override
+        public String toString() {
+            return "[" + lower + ", " + upper + "]";
+        }
+    }
+
+    /**
+     * 去重并保留索引(保持原始顺序)
+     * 实测值满足条件
+     */
+    public static Map<String,List<Integer>> deduplicateWithIndices(Range range,List<Object> list,List<Object> list2) {
+        if (list == null || list.isEmpty()) {
+            return null;
+        }
+        // 使用LinkedHashMap保持插入顺序
+        Map<String, List<Integer>> indicesMap = new LinkedHashMap<>();
+        for (int i = 0; i < list.size(); i++) {
+            String element = (String) list.get(i);
+            //跳过空字符串和非数字字符串
+            if(StringUtils.isEmpty(element) || !StringUtils.isNumber(element)){
+                continue;
+            }
+            double v = Double.parseDouble((String) list2.get(i));
+            //如果这个偏差值小于下限或者大于上限,则跳过
+            if(v < range.lower || v > range.upper){
+                continue;
+            }
+
+            indicesMap.computeIfAbsent(element, k -> new ArrayList<>()).add(i);
+        }
+
+        return indicesMap;
+    }
 
 }

+ 2 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java

@@ -1603,7 +1603,8 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                             } else {
                                 putEle(f, ele, currentMap, fd);
                                //公式获取值
-                                Object data = Expression.parse(formula.getFormula()).calculate(currentMap);
+                                Expression parse = Expression.parse(formula.getFormula());
+                                Object data = parse.calculate(currentMap);
                                 //如果有空串,也要加进data不然表格数据顺序会混乱
                                 try {
                                     Object e = currentMap.get("E");