瀏覽代碼

公式解析

yangyj 3 年之前
父節點
當前提交
17efcb4682

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

@@ -15,9 +15,9 @@ import java.util.List;
 @Data
 public class FormData {
     /**
-     * 元素key
+     * 元素
      */
-    private String eKey;
+    private String code;
     /**
      * 元素名称
      */
@@ -40,7 +40,7 @@ public class FormData {
     /**
      * 内容
      */
-    private List<Object[][]> values;
+    private List<List<Object>> values;
     /**
      * 公式脚本
      */
@@ -50,5 +50,13 @@ public class FormData {
      */
     private  Integer groupId;
 
+    public FormData() {
+    }
+    public FormData(String code, List<List<Object>> values, Formula formula, Integer groupId) {
+        this.code = code;
+        this.values = values;
+        this.formula = formula;
+        this.groupId = groupId;
+    }
 
 }

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

@@ -12,15 +12,17 @@ import org.springblade.core.mp.support.Query;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.BeanUtil;
 import org.springblade.core.tool.utils.Func;
+import org.springblade.manager.dto.FormData;
 import org.springblade.manager.dto.FormulaBean;
 import org.springblade.manager.entity.Formula;
 import org.springblade.manager.service.impl.FormulaServiceImpl;
 import org.springblade.manager.wrapper.FormulaWrapper;
-import org.springblade.system.user.entity.User;
 import org.springframework.beans.BeanUtils;
 import org.springframework.web.bind.annotation.*;
 import springfox.documentation.annotations.ApiIgnore;
 
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
 
@@ -118,6 +120,29 @@ public class FormulaController {
     }
 
 
+    @GetMapping("/execute")
+    @ApiIgnore
+    public R execute() {
+        List<FormData> list = new ArrayList<>();
+        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);
+       return R.success("执行完成");
+    }
+
+
+    public FormData makeFd(String fs,String code,Integer groupId,Object ...obs){
+        List<List<Object>> ld = new ArrayList<>();
+        ld.add(Arrays.asList(obs));
+        Formula f= new Formula();
+        f.setFormula(fs);
+        return new FormData(code,ld,f,groupId);
+    }
+
+
+
+
 
 
 }

+ 67 - 16
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java

@@ -1,11 +1,15 @@
 package org.springblade.manager.service.impl;
 
 
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.jfireel.expression.Expression;
+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.manager.dto.FormData;
 import org.springblade.manager.entity.Formula;
-import org.springblade.manager.entity.WbsFormElement;
+import org.springblade.manager.entity.WbsParam;
 import org.springblade.manager.entity.WbsTree;
 import org.springblade.manager.mapper.FormulaMapper;
 import org.springblade.manager.service.IFormulaService;
@@ -21,23 +25,41 @@ import java.util.stream.Collectors;
  * @Date 2022/6/9 14:29
  * @description TODO
  */
+
 @Service
+@AllArgsConstructor
 public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula> implements IFormulaService {
-    /**
-     * @Description
-     * @Param [variables, list:表单数据, formulas:同一个wbsId]
-     * @return void
-     * @Author yangyj
-     * @Date 2022.06.15 16:34
-     **/
-    public void execute(Map variables, List<FormData> list,List<Formula> formulas ){
+
+    private final WbsParamServiceImpl wpService;
+
+
+    public final static String WP="WP";
+    public final static String CHAIN="trees";
+    public final static String FC="FC.";
+
+    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> currentMap = new HashMap<>();
+            /*预设变量start*/
             List<WbsTree> trees = new ArrayList<>();
             for(int i=0;i<6;i++){
                  WbsTree t= new WbsTree();
-                 t.setFullName("第"+i+"层");
+                 t.setDeptName("第"+i+"层");
+                 trees.add(t);
+            }
+            List<WbsParam> wps = this.wpService.list(Wrappers.<WbsParam>lambdaQuery().eq(WbsParam::getWbsId,123456));
+            Map<String,Object> wpMap= new HashMap<>();
+            if(CollectionUtil.isNotEmpty(wps)){
+                for(WbsParam p:wps){
+                     wpMap.put(p.getK(),p.getV());
+                }
             }
+           /*预设变量end*/
+
              /*没有依赖的*/
              List<FormData> simple=map.get(false);
              if(CollectionUtil.isNotEmpty(simple)){
@@ -49,16 +71,45 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                   sort(rely,((rely.size()+1)/2)*rely.size());
                   total.addAll(rely);
              }
+
             if(CollectionUtil.isNotEmpty(total)){
-                /*预处理*/
-                for(FormData fd:total){
+                currentMap.put(WP,wpMap);
+                currentMap.put(CHAIN,trees.stream().map(WbsTree::getDeptName).collect(Collectors.toList()));
 
+                for(FormData fd:total){
+                      /*存入数据*/
+                      if(CollectionUtil.isNotEmpty(fd.getValues())){
+                           Map<String,Object> tmpMap = new HashMap<>();
+                           for(int i=0;i<fd.getValues().size();i++){
+                              tmpMap.put("p"+i,fd.getValues().get(i));
+                           }
+                           Map<String,Object> tableMap = (Map<String, Object>) variables.get(fd.getCode());
+                           if(tableMap==null){
+                               tableMap= new HashMap<>();
+                               variables.put(fd.getCode(),tableMap);
+                           }
+                           tableMap.put(fd.getGroupId().toString(),tmpMap);
+                      }
+                      /*预处理公式脚本*/
+                      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()+"'");
+                      }
+                      fd.getFormula().setFormula(tmp);
+                }
+                /*执行公式*/
+                for(FormData fd:total){
+                 Object data =   Expression.parse(fd.getFormula().getFormula()).calculate(currentMap);
+                 fd.getValues().add(new ArrayList<>(Collections.singletonList(data)));
                 }
             }
+        System.out.println();
     }
 
-
-
+    public static final String WP_REG= "(?<=P\\[)[^]]+(?=\\])";
+    public static final  Pattern PP = Pattern.compile(WP_REG);
 
     /**
      * 依赖排序
@@ -66,7 +117,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     public static final String ELE_CODE_REG= "(?<=E\\[)[^]]+(?=\\])";
     public static final  Pattern P = Pattern.compile(ELE_CODE_REG);
     public  static void sort( List<FormData> list,int n){
-        System.out.println("剩余计算次数:"+n+"次");
+        /*System.out.println("剩余计算次数:"+n+"次");*/
         if(move(list)&&n>0){
             sort(list,--n);
         }
@@ -79,7 +130,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
             while (m.find()){
                 cp.add(m.group());
             }
-            Map<Boolean,List<FormData>>  map= list.stream().skip(i+1).collect(Collectors.partitioningBy(e->cp.contains(e.getEKey())));
+            Map<Boolean,List<FormData>>  map= list.stream().skip(i+1).collect(Collectors.partitioningBy(e->cp.contains(e.getCode())));
             List<FormData> match =map.get(true);
             if(CollectionUtil.isNotEmpty(match)){
                 for(FormData r:match){