Browse Source

公式解析

yangyj 3 years ago
parent
commit
1dcf4301ec

+ 5 - 1
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/FormData.java

@@ -15,9 +15,13 @@ import java.util.List;
 @Data
 public class FormData {
     /**
-     * 元素码
+     * 元素码:表名_字段名
      */
     private String code;
+    /**
+     * 步长
+     */
+    private Integer step;
     /**
      * 元素名称
      */

+ 6 - 6
blade-service/blade-manager/src/main/java/com/jfireel/expression/node/MethodNode.java

@@ -13,32 +13,32 @@ public interface MethodNode extends CalculateNode {
 				Object argeValue = args[i];
 				switch (convertTypes[i]) {
 				case INT:
-					if (argeValue instanceof Integer == false) {
+					if (!(argeValue instanceof Integer)) {
 						args[i] = ((Number) argeValue).intValue();
 					}
 					break;
 				case LONG:
-					if (argeValue instanceof Long == false) {
+					if (!(argeValue instanceof Long)) {
 						args[i] = ((Number) argeValue).longValue();
 					}
 					break;
 				case SHORT:
-					if (argeValue instanceof Short == false) {
+					if (!(argeValue instanceof Short)) {
 						args[i] = ((Number) argeValue).shortValue();
 					}
 					break;
 				case FLOAT:
-					if (argeValue instanceof Float == false) {
+					if (!(argeValue instanceof Float)) {
 						args[i] = ((Number) argeValue).floatValue();
 					}
 					break;
 				case DOUBLE:
-					if (argeValue instanceof Double == false) {
+					if (!(argeValue instanceof Double)) {
 						args[i] = ((Number) argeValue).doubleValue();
 					}
 					break;
 				case BYTE:
-					if (argeValue instanceof Byte == false) {
+					if (!(argeValue instanceof Byte)) {
 						args[i] = ((Number) argeValue).byteValue();
 					}
 					break;

+ 42 - 3
blade-service/blade-manager/src/main/java/com/jfireel/expression/node/impl/StaticObjectMethodNode.java

@@ -58,12 +58,11 @@ public class StaticObjectMethodNode implements MethodNode {
 							Class<?>[] parameterTypes = each.getParameterTypes();
 							for (int i = 0; i < args.length; i++) {
 								if (parameterTypes[i].isPrimitive()) {
-									if (args[i] == null || MethodNodeUtil.isWrapType(parameterTypes[i],
-											args[i].getClass()) == false) {
+									if (args[i] == null || !MethodNodeUtil.isWrapType(parameterTypes[i], args[i].getClass())) {
 										continue nextmethod;
 									}
 								} else if (args[i] != null
-										&& parameterTypes[i].isAssignableFrom(args[i].getClass()) == false) {
+										&& !parameterTypes[i].isAssignableFrom(args[i].getClass())) {
 									continue nextmethod;
 								}
 							}
@@ -80,6 +79,46 @@ public class StaticObjectMethodNode implements MethodNode {
 		return method;
 	}
 
+
+/**
+	private Method getMethod(Object[] args) {
+		if (method == null) {
+			synchronized (this) {
+				if (method == null) {
+					nextmethod: for (Method each : beanType.getMethods()) {
+						if (Modifier.isStatic(each.getModifiers()) && each.getName().equals(methodName)) {
+							Class<?>[] parameterTypes = each.getParameterTypes();
+							 if(each.getParameterTypes().length==1&&each.getParameterTypes()[0].getName().startsWith("[")){
+								 convertTypes = MethodNodeUtil.buildConvertTypes(parameterTypes);
+								 each.setAccessible(true);
+								 method = each;
+								 return method;
+							 }else if(each.getParameterTypes().length == args.length){
+								 for (int i = 0; i < args.length; i++) {
+									 if (parameterTypes[i].isPrimitive()) {
+										 if (args[i] == null || !MethodNodeUtil.isWrapType(parameterTypes[i], args[i].getClass())) {
+											 continue nextmethod;
+										 }
+									 } else if (args[i] != null && !parameterTypes[i].isAssignableFrom(args[i].getClass())) {
+										 continue nextmethod;
+									 }
+								 }
+								 convertTypes = MethodNodeUtil.buildConvertTypes(parameterTypes);
+								 each.setAccessible(true);
+								 method = each;
+								 return method;
+							 }
+
+						}
+					}
+				}
+				throw new NullPointerException("没有在类" + beanType.getName() + "找到静态方法" + methodName);
+			}
+		}
+		return method;
+	}
+ */
+	@Override
 	public void setArgsNodes(CalculateNode[] argsNodes) {
 		this.argsNodes = argsNodes;
 		type = Token.METHOD_RESULT;

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

@@ -779,7 +779,30 @@ public class CustomFunction {
 		}
 		return result;
 	}
-	
+	public static boolean isNumber(Object value) {
+		if(Func.isEmpty(value)){
+			return  false;
+		}
+		if(value instanceof  Number){
+			return true;
+		}
+		String pattern = "^[+-]?\\d+(\\.\\d+)?$";
+		Pattern r = Pattern.compile(pattern);
+		Matcher m = r.matcher(String.valueOf(value));
+		return m.matches();
+	}
+	public static boolean isNotNumber(Object value){
+		return !isNumber(value);
+	}
+
+	public static Object avg( List<Object> list) {
+		 if(list!=null){
+			 if(list.stream().noneMatch(CustomFunction::isNotNumber)){
+			       return list.stream().map(String::valueOf).mapToDouble(Double::parseDouble).average();
+			 }
+		 }
+	     return null;
+	}
 
 	
 	/**
@@ -1620,6 +1643,20 @@ public class CustomFunction {
 		return 0;
 	}
 
+
+
+	/**
+	 * @Description 立方
+	 * @Param [base]
+	 * @return java.lang.Object
+	 * @Author yangyj
+	 * @Date 2022.06.24 16:48
+	 **/
+	public static Object cube(Object base){
+          return  pow(base,3);
+	}
+
+
 	/**
 	 * @Description   平方
 	 * @Param [a:底數, scale:结果取整]

+ 7 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/FormulaController.java

@@ -127,7 +127,13 @@ public class FormulaController {
         list.add(makeFd("FC.tree(trees,WP[snake])","t-f1",0,""));
         list.add(makeFd("FC.avg(E[ele852])","ele100",0,""));
         list.add(makeFd("","ele852",0,1,2,3,4,5,6));
-       this.service.execute(list);
+        list.add(makeFd("(E[a]+E[b])/2+E[c]*E[d]","szys",0,""));
+        list.add(makeFd("","a",0,2,2,2,2,2));
+        list.add(makeFd("","b",0,3,3,6,3,8));
+        list.add(makeFd("","c",0,5,3,7,3,9));
+        list.add(makeFd("","d",0,10,7,2,5,5));
+
+        this.service.execute(list);
        return R.success("执行完成");
     }
 

+ 26 - 3
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java

@@ -7,6 +7,7 @@ import com.mixsmart.utils.CustomFunction;
 import lombok.AllArgsConstructor;
 import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springblade.core.tool.utils.CollectionUtil;
+import org.springblade.core.tool.utils.Func;
 import org.springblade.manager.dto.FormData;
 import org.springblade.manager.entity.Formula;
 import org.springblade.manager.entity.WbsParam;
@@ -37,6 +38,9 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     public final static String CHAIN="trees";
     public final static String FC="FC.";
 
+
+    public static final String POLY_REG= "(avg|min|max|sum)\\([^)]+\\)";
+    public static final  Pattern POLY = Pattern.compile(POLY_REG);
     public void execute( List<FormData> list ){
              Map<Boolean,List<FormData>> map = list.stream().collect(Collectors.partitioningBy(e->e!=null&&e.getFormula().getFormula().contains("E[")));
             List<FormData>total = new ArrayList<>();
@@ -75,7 +79,8 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
             if(CollectionUtil.isNotEmpty(total)){
                 currentMap.put(WP,wpMap);
                 currentMap.put(CHAIN,trees.stream().map(WbsTree::getDeptName).collect(Collectors.toList()));
-
+                Map<String,Object> E=new HashMap<>();
+                currentMap.put("E",E);
                 for(FormData fd:total){
                       /*存入数据*/
                       if(CollectionUtil.isNotEmpty(fd.getValues())){
@@ -83,6 +88,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                            for(int i=0;i<fd.getValues().size();i++){
                               tmpMap.put("p"+i,fd.getValues().get(i));
                            }
+                          E.put(fd.getCode(),fd.getValues().get(0));
                            Map<String,Object> tableMap = (Map<String, Object>) variables.get(fd.getCode());
                            if(tableMap==null){
                                tableMap= new HashMap<>();
@@ -97,12 +103,29 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                       while (m.find()){
                         tmp= tmp.replace(m.group(),"'"+m.group()+"'");
                       }
+                       Matcher m2 = P.matcher(tmp);
+                    while (m2.find()){
+                        tmp= tmp.replace(m2.group(),"'"+m2.group()+"'");
+                    }
                       fd.getFormula().setFormula(tmp);
                 }
                 /*执行公式*/
+                /*集合公式预处理*/
+                for(FormData fd:total){
+                    String formula=fd.getFormula().getFormula();
+                    if(formula.contains(CustomFunction.CLASS_CALL+"avg(")||formula.contains(CustomFunction.CLASS_CALL+"min(")||formula.contains(CustomFunction.CLASS_CALL+"max(")||formula.contains(CustomFunction.CLASS_CALL+"sum(")){
+                        Matcher m = POLY.matcher(formula);
+                        while (m.find()){
+                            Object data =   Expression.parse(m.group()).calculate(currentMap);
+                            formula = formula.replace(m.group(),data.toString());
+                        }
+                    }
+                }
                 for(FormData fd:total){
-                 Object data =   Expression.parse(fd.getFormula().getFormula()).calculate(currentMap);
-                 fd.getValues().add(new ArrayList<>(Collections.singletonList(data)));
+                    if(Func.isNotBlank(fd.getFormula().getFormula())){
+                        Object data =   Expression.parse(fd.getFormula().getFormula()).calculate(currentMap);
+                        fd.getValues().add(new ArrayList<>(Collections.singletonList(data)));
+                    }
                 }
             }
         System.out.println();