Browse Source

公式相关

yangyj 2 years ago
parent
commit
fd71972a18

+ 3 - 3
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/ElementData.java

@@ -12,12 +12,12 @@ public class ElementData {
     /**
      *  表的自然顺序,同一张表复制N次,index代表该数据在第几张
      */
-    Integer index;
+   private Integer index;
     /**
      * 数据组Id,一道工序可能会在不同时间或者空间测量多组数据
      */
-    Integer groupId;
-    Object  value;
+   private   Integer groupId;
+   private   Object  value;
 
     public Integer getIndex() {
         return index;

+ 23 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/FormulaClient.java

@@ -0,0 +1,23 @@
+package org.springblade.manager.feign;
+
+import org.springblade.manager.dto.FormData;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+
+import java.util.List;
+
+import static org.springblade.core.launch.constant.AppConstant.APPLICATION_NAME_PREFIX;
+
+/**
+ * @author yangyj
+ */
+@FeignClient(value = APPLICATION_NAME_PREFIX +  "manager")
+public interface FormulaClient {
+    /**
+     * 接口前缀
+     */
+    String API_PREFIX = "/api/manager/formula";
+    @PostMapping(API_PREFIX+"execute")
+    void formulaExecute();
+
+}

+ 9 - 0
blade-service/blade-business/src/main/java/org/springblade/business/controller/MileageController.java

@@ -26,9 +26,15 @@ import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.CollectionUtil;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.StringUtil;
+import org.springblade.manager.dto.ElementData;
+import org.springblade.manager.dto.FormData;
+import org.springblade.manager.entity.Formula;
+import org.springblade.manager.feign.FormulaClient;
 import org.springframework.beans.BeanUtils;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
+import springfox.documentation.annotations.ApiIgnore;
+
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.io.OutputStream;
@@ -37,6 +43,7 @@ import java.net.URLEncoder;
 import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
 /**
  * @author yangyj
@@ -302,4 +309,6 @@ public class MileageController {
     }
 
 
+
+
 }

+ 7 - 7
blade-service/blade-manager/pom.xml

@@ -14,13 +14,13 @@
 <version>${bladex.project.version}</version>
     <packaging>jar</packaging>
 
-    <repositories>
-        <repository>
-            <id>com.e-iceblue</id>
-            <name>e-iceblue</name>
-            <url>https://repo.e-iceblue.cn/repository/maven-public/</url>
-        </repository>
-    </repositories>
+<!--    <repositories>-->
+<!--        <repository>-->
+<!--            <id>com.e-iceblue</id>-->
+<!--            <name>e-iceblue</name>-->
+<!--            <url>https://repo.e-iceblue.cn/repository/maven-public/</url>-->
+<!--        </repository>-->
+<!--    </repositories>-->
 
     <dependencies>
         <dependency>

+ 4 - 15
blade-service/blade-manager/src/main/java/com/mixsmart/utils/CustomFunction.java

@@ -1,22 +1,11 @@
 package com.mixsmart.utils;
 
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
+
 import com.jfireel.expression.Expression;
 import com.mixsmart.security.SecurityUtils;
 import org.apache.commons.collections4.MapUtils;
-import org.apache.http.Consts;
-import org.apache.http.HttpResponse;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.message.BasicNameValuePair;
 import org.springblade.core.tool.utils.CollectionUtil;
 import org.springblade.core.tool.utils.Func;
-
-import java.io.*;
 import java.math.BigDecimal;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
@@ -24,7 +13,6 @@ import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
-
 import static java.math.BigDecimal.ROUND_CEILING;
 import static java.math.BigDecimal.ROUND_HALF_UP;
 
@@ -2057,10 +2045,10 @@ public class CustomFunction {
 		if(b!=null&&Func.isNotBlank(b.toString())){
 			String s = b.toString();
 			boolean fi  = true;
-			if(s.contains("<")&&s.contains(">")){
+			if(s.contains("<")||s.contains(">")){
 				 String[] arr=s.split("&&");
 				 for(String e:arr){
-					 if(!Boolean.parseBoolean(Expression.parse(e).calculate())){
+					 if(!(boolean)Expression.parse(e).calculate()){
 					 	fi=false;
 					 	break;
 					 };
@@ -3691,6 +3679,7 @@ public class CustomFunction {
 
 
 //	public static void main(String[] args)  {
+//		System.out.println(Expression.parse("15<=2").calculate().toString());
 //	}
 
 }

+ 10 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/FormulaController.java

@@ -136,6 +136,16 @@ public class FormulaController {
         list.add(makeFd("","b","",0,3,3,6,3,8));
         list.add(makeFd("","c","",0,5.5,3,7,3,9));
         list.add(makeFd("","d","",0,10,7,2,5,5));
+        list.add(makeFd("","T","","true","true"));
+        list.add(makeFd("","F","","false","false"));
+        list.add(makeFd("","cp1","",10,20));
+        list.add(makeFd("","cp2","","false"));
+        list.add(makeFd("FC.ifelse(0<E[cp1]&&E[cp1]<=15,E[T],E[F])","FT","F,T,cp1"));
+        list.add(makeFd("","head","","www.","www."));
+        list.add(makeFd("","tail","","badu.com","jd.com"));
+        list.add(makeFd("E[head]+E[tail]","concat","head,tail"));
+        list.add(makeFd("","zms","","19","5"));
+        list.add(makeFd("FC.pow(E[zms],2)","pow","zms"));
 
         this.service.execute(list);
        return R.success("执行完成");

+ 47 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/feign/FormulaClientImpl.java

@@ -0,0 +1,47 @@
+package org.springblade.manager.feign;
+
+import lombok.AllArgsConstructor;
+import org.springblade.manager.dto.ElementData;
+import org.springblade.manager.dto.FormData;
+import org.springblade.manager.entity.Formula;
+import org.springblade.manager.service.IFormulaService;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author yangyj
+ * @Date 2022/7/6 13:54
+ * @description TODO
+ */
+@RestController
+@AllArgsConstructor
+public class FormulaClientImpl implements  FormulaClient{
+    private  final IFormulaService service;
+    @Override
+    public void formulaExecute() {
+        List<FormData> list = new ArrayList<>();
+        list.add(makeFd("FC.tree(trees,WP[snake])","t-f1",""));
+        list.add(makeFd("FC.avg(E[ele852])","ele100","ele852"));
+        list.add(makeFd("","ele852","",0,1,2,3,4,5,6));
+        list.add(makeFd("(E[a]+E[b])/2+E[c]*E[d]","szys","a,b,c,d"));
+        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.5,3,7,3,9));
+        list.add(makeFd("","d","",0,10,7,2,5,5));
+        service.execute(list);
+    }
+    public FormData makeFd(String fs,String code,String rely,Object ...obs){
+        Formula f= new Formula();
+        f.setRely(rely);
+        f.setFormula(fs);
+        List<ElementData> list = new ArrayList<>();
+        if(obs!=null){
+            list= Arrays.stream(obs).map(e->new ElementData(0,0,e)).collect(Collectors.toList());
+        }
+        return new FormData(code, list,f);
+    }
+}

+ 3 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/feign/ProjectClientImpl.java

@@ -7,6 +7,9 @@ import org.springframework.web.bind.annotation.RestController;
 
 import java.util.List;
 
+/**
+ * @author yangyj
+ */
 @RestController
 @AllArgsConstructor
 public class ProjectClientImpl implements ProjectClient {

+ 8 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/service/IFormulaService.java

@@ -1,11 +1,18 @@
 package org.springblade.manager.service;
 
 import org.springblade.core.mp.base.BaseService;
+import org.springblade.manager.dto.FormData;
 import org.springblade.manager.entity.Formula;
 
+import java.util.List;
+
 /**
  * @author yangyj
  */
 public interface IFormulaService extends BaseService<Formula> {
-
+    /**
+     *
+     * @param list
+     */
+    void execute(List<FormData> list );
 }

+ 58 - 19
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java

@@ -1,6 +1,7 @@
 package org.springblade.manager.service.impl;
 
 
+import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.jfireel.expression.Expression;
 import com.mixsmart.utils.CustomFunction;
@@ -40,14 +41,13 @@ 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 ){
+    @Override
+    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<>();
             /*用来保存所有变量*/
-            Map<String,Object> variables = new HashMap<>();
             Map<String,Object> constantMap = new HashMap<>();
             /*预设变量start*/
             List<WbsTree> trees = new ArrayList<>();
@@ -84,48 +84,84 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                       /*预处理公式脚本*/
                       String tmp =fd.getFormula().getFormula();
                       tmp = tmp.replace(FC, CustomFunction.CLASS_CALL);
-                      Matcher m = PP.matcher(tmp);
-                      while (m.find()){
-                        tmp= tmp.replace(m.group(),"'"+m.group()+"'");
+
+                      if(tmp.contains("WP[")){
+                          Matcher m = PP.matcher(tmp);
+                          while (m.find()){
+                              tmp= tmp.replace("WP"+m.group()+"]","WP['"+m.group()+"']");
+                          }
                       }
-                       Matcher m2 = P.matcher(tmp);
-                      while (m2.find()){
-                          tmp= tmp.replace(m2.group(),"'"+m2.group()+"'");
+
+                    if(tmp.contains(CustomFunction.CLASS_CALL+"ifelse")){
+                        Matcher im =IF.matcher(tmp);
+                        while (im.find()){
+                            String rep =im.group();
+                            Matcher fm=P.matcher(rep);
+                            while (fm.find()){
+                                rep=rep.replace(fm.group(),"'+"+fm.group()+"+'");
+                                rep="'"+rep+"'";
+                            }
+                            tmp=tmp.replace(im.group(),rep);
+                        }
+                    }
+
+                      if(tmp.contains("E[")){
+                          Matcher m2 = P.matcher(tmp);
+                          while (m2.find()){
+                              tmp= tmp.replace("E["+m2.group()+"]","E['"+m2.group()+"']");
+                          }
                       }
-                        fd.getFormula().setFormula(tmp);
-                }
 
+
+
+
+
+                    fd.getFormula().setFormula(tmp);
+                }
+               /*公式执行*/
                 for(FormData fd:total){
                     Formula formula= fd.getFormula();
+
                     if(formula!=null){
                         String f=formula.getFormula();
                         if(Func.isNotBlank(f)){
+
                             Map<String, Object> currentMap = new HashMap<>(constantMap);
                             Map<String,Object> E = getMap(currentMap,"E");
                             List<String>  relyList = fd.getFormula().getRelyList();
+
                             if(CollectionUtil.isNotEmpty(relyList)){
+
                                 List<FormData>  ele = total.stream().filter(e->relyList.contains(e.getCode())).collect(Collectors.toList());
+
                                 if(f.contains(CustomFunction.CLASS_CALL+"avg(")||f.contains(CustomFunction.CLASS_CALL+"min(")||f.contains(CustomFunction.CLASS_CALL+"max(")||f.contains(CustomFunction.CLASS_CALL+"sum(")){
+                                    /*聚合*/
                                     Matcher m = POLY.matcher(f);
                                     while (m.find()){
                                         List<String> elementCodes=CustomFunction.parseElementCode(m.group(2));
                                         List<FormData> tmp = ele.stream().filter(e->elementCodes.contains(e.getCode())).collect(Collectors.toList());
                                         ele.removeAll(tmp);
+
                                         tmp.forEach(e-> E.put(e.getCode(),e.getValues().stream().map(ElementData::getValue).collect(Collectors.toList())));
                                         Object data =   Expression.parse(CustomFunction.CLASS_CALL+m.group()).calculate(currentMap);
+
                                         f = f.replace(CustomFunction.CLASS_CALL+m.group(),data.toString());
                                         fd.getFormula().setFormula(f);
                                     }
                                 }
                                 if(CollectionUtil.isNotEmpty(ele)){
                                     Map<Integer,Map<String,List<Object>>> dataSource = new HashMap<>();
+
                                     for(FormData e:ele){
                                        Map<Integer,List<ElementData>> m = e.getValues().stream().collect(Collectors.groupingBy(ElementData::getGroupId));
+
                                        for(Map.Entry<Integer,List<ElementData>> entry:m.entrySet()){
                                            Map<String,List<Object>> t = dataSource.computeIfAbsent(entry.getKey(), k -> new HashMap());
                                            t.put(e.getCode(),entry.getValue().stream().map(ElementData::getValue).collect(Collectors.toList()));
                                        }
+
                                     }
+
                                     if(dataSource.size()>0){
                                         for(Map.Entry<Integer,Map<String,List<Object>>> entry:dataSource.entrySet()){
                                             if(entry.getValue().keySet().size()>=ele.size()){
@@ -134,6 +170,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                                             }
                                         }
                                     }
+
                                 }else{
                                     fd.getValues().add(new ElementData(0,0,Expression.parse(formula.getFormula()).calculate(currentMap)));
                                 }
@@ -144,9 +181,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                     }
                 }
             }
-//        total.stream().filter(e->Func.isNotBlank(e.getFormula().getFormula())).map(FormData::getValues).forEach(e->e.stream().map(ElementData::getValue).forEach(System.out::println));
-        total.stream().filter(e->Func.isNotBlank(e.getFormula().getFormula())).map(FormData::getValues).forEach(System.out::println);
-
+        total.stream().filter(e->Func.isNotBlank(e.getFormula().getFormula())).map(FormData::getValues).forEach(e->e.stream().map(JSON::toJSONString).forEach(System.out::println));
     }
 
     public  Map<String,Object> getMap(Map<String,Object> main,String key){
@@ -159,24 +194,25 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     }
 
     public  List<ElementData> slice(Map<String,List<Object>> elementMap,Map<String,Object> constantMap,String formula,Integer groupId){
+
         int min =0;
         List<ElementData> result = new ArrayList<>();
+
         for(Map.Entry<String,List<Object>> entry:elementMap.entrySet()){
             List<Object> tmp =  entry.getValue();
-            if(min==0){
-                min=tmp.size();
-            }else{
-                min= Math.min(min,tmp.size());
-            }
+            min = min==0?tmp.size():Math.min(min,tmp.size());
         }
         if(min>0){
             List<LocalVariable>  lvab= new ArrayList<>();
+
             for(int i=0;i<min;i++){
                 Map<String, Object> currentMap = new HashMap<>(constantMap);
                 Map<String,Object> E=getMap(currentMap,"E");
+
                 for(Map.Entry<String,List<Object>> e:elementMap.entrySet()){
                     E.put(e.getKey(),e.getValue().get(i));
                 }
+
                 lvab.add(new LocalVariable(i,formula,currentMap));
             }
             /*并发执行*/
@@ -184,6 +220,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                 Object data =Expression.parse(e.getFormula()).calculate(e.getCurrentMap());
                 return new ElementData(e.getIndex(),groupId,data);
             }).collect(Collectors.toList());
+
             if(CollectionUtil.isNotEmpty(r)){
                 result.addAll(r);
             }
@@ -195,6 +232,8 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     public static final String WP_REG= "(?<=P\\[)[^]]+(?=\\])";
     public static final  Pattern PP = Pattern.compile(WP_REG);
 
+    public static final String IF_REG= "(?<=T\\(com.mixsmart.utils.CustomFunction\\).ifelse\\()[^,]+(?=,)";
+    public static final  Pattern IF = Pattern.compile(WP_REG);
     /**
      * 依赖排序
      */