yangyj hace 3 años
padre
commit
4e0ea5dc48

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

@@ -23,6 +23,27 @@ public class ElementData {
    private   Integer groupId;
    private   Object  value;
 
+   private   Integer  x;
+   private   Integer  y;
+
+
+
+    public Integer getX() {
+        return x;
+    }
+
+    public void setX(Integer x) {
+        this.x = x;
+    }
+
+    public Integer getY() {
+        return y;
+    }
+
+    public void setY(Integer y) {
+        this.y = y;
+    }
+
     public Integer getIndex() {
         return index;
     }

+ 4 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/FormData.java

@@ -51,6 +51,10 @@ public class FormData {
      */
     private Formula formula;
 
+    /**总共多少页,有些公式只生成一条数据,所以必须每一页复制一条
+     * */
+    private Integer pages;
+
     public static final String CODE_REG="[^:]+:[^:]+";
 
     public FormData() {

+ 16 - 5
blade-service/blade-manager/src/main/java/org/springblade/manager/service/IFormulaService.java

@@ -11,11 +11,22 @@ import java.util.List;
  * @author yangyj
  */
 public interface IFormulaService extends BaseService<Formula> {
-    /**
-     *
-     * @param list
-     */
+
     void execute(List<FormData> list,Long contractId,Long primaryKeyId);
     void execute(TableElementConverter tec);
-
+    /**
+     * 变量准备*/
+    void init(List<FormData> list,Long contractId,Long primaryKeyId);
+    /**
+     * 依赖排序*/
+    void sort();
+    /**
+     * 公式预处理*/
+    void pre();
+    /**
+     * 特殊公式处理*/
+    void special();
+    /**
+     * 公式运算*/
+    void calculate();
 }

+ 141 - 154
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java

@@ -21,6 +21,7 @@ import org.springblade.manager.formula.FormulaStrategyFactory;
 import org.springblade.manager.formula.impl.TableElementConverter;
 import org.springblade.manager.mapper.FormulaMapper;
 import org.springblade.manager.service.IFormulaService;
+import org.springblade.manager.service.IWbsParamService;
 import org.springblade.manager.service.IWbsTreeContractService;
 import org.springframework.stereotype.Service;
 
@@ -39,7 +40,7 @@ import java.util.stream.Collectors;
 @AllArgsConstructor
 public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula> implements IFormulaService {
 
-    private final WbsParamServiceImpl wpService;
+    private final IWbsParamService wpService;
     private final MileageClient mileageClient;
     private final IWbsTreeContractService treeContractService;
     private final FormulaStrategyFactory formulaStrategyFactory;
@@ -52,168 +53,147 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     public static final String POLY_REG= "(avg|min|max|sum)\\(([^)]+)\\)";
     public static final Pattern POLY = Pattern.compile(POLY_REG);
     public static final Pattern MILE_P = Pattern.compile("(?<=MILE<)([^,]+),([^,]+)(?=,)");
+    private  Map<String,Object> constantMap;
+    private  List<FormData> formDataList;
+
 
 
     /**
-     * @Description
      * @Param [list: 源数据, contractId: 合同段id, primaryKeyId: wbs节点id]
-     * @return void
      * @Author yangyj
      * @Date 2022.08.03 14:03
      **/
     @Override
     public void execute(List<FormData> list ,Long contractId,Long primaryKeyId){
+              /*初始化变量>>依赖排序>>预处理>>特殊公式>>通用公式执行*/
+//             this.init(list,contractId,primaryKeyId).sort().pre().special().calculate();
+    }
 
-/*        contractId=888888L;*/
-        /*变量准备*/
-        /*依赖排序*/
-        /*公式预处理*/
-        /*公式运算*/
-        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> constantMap = new HashMap<>(20);
-            constantMap.put("contractId",contractId);
-            /*预设变量start*/
-            List<WbsTreeContract> trees = new ArrayList<>();
-            List<WbsTreeContract> nodes = treeContractService.searchParentAllNode(primaryKeyId,contractId);
-            if(CollectionUtil.isEmpty(nodes)){
-                for(int i=0;i<6;i++){
-                    WbsTreeContract t= new WbsTreeContract();
-                    t.setDeptName("第"+i+"层");
-                    trees.add(t);
-                }
-            }else{
-                trees=nodes;
-            }
-            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());
-                }
+    @Override
+    public void execute(TableElementConverter tec) {
+        WbsTreeContract one = this.treeContractService.getById(tec.getTableInfoList().get(0).getPkeyId());
+        this.execute(tec.getFds(),tec.getContractId(),Func.isNotEmpty(one.getOldId())?Long.parseLong(one.getOldId()):one.getParentId());
+    }
+
+    @Override
+    public void init(List<FormData> list,Long contractId,Long primaryKeyId) {
+        this.constantMap=new HashMap<>(100);
+        this.formDataList=list;
+        this.constantMap.put("contractId",contractId);
+        List<WbsTreeContract> nodes = treeContractService.searchParentAllNode(primaryKeyId,contractId);
+        this.constantMap.put(CHAIN,nodes.stream().map(WbsTreeContract::getFullName).collect(Collectors.toList()));
+        List<WbsParam> wps = this.wpService.list(Wrappers.<WbsParam>lambdaQuery().eq(WbsParam::getWbsId,primaryKeyId));
+        Map<String,Object> wpMap= new HashMap<>(wps.size()*2);
+        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)){
-                 total.addAll(simple);
-             }
-            /*有依赖的*/
-             List<FormData> rely= map.get(true);
-             if(CollectionUtil.isNotEmpty(rely)){
-                  sort(rely,((rely.size()+1)/2)*rely.size());
-                  total.addAll(rely);
-             }
-            if(CollectionUtil.isNotEmpty(total)){
-                /*变量环境加载*/
-                constantMap.put(WP,wpMap);
-                constantMap.put(CHAIN,trees.stream().map(WbsTreeContract::getDeptName).collect(Collectors.toList()));
-                for(FormData fd:total){
-                      /*预处理公式脚本*/
-                      String tmp =fd.getFormula().getFormula();
-                      tmp = tmp.replace(FC, CustomFunction.CLASS_CALL);
-
-                      if(tmp.contains("WP[")){
-                          Matcher m = PP.matcher(tmp);
-                          while (m.find()){
-                              tmp= tmp.replace("WP"+m.group()+"]","WP['"+m.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);
+        }
+        this.constantMap.put(WP,wpMap);
+//        return this;
+    }
+
+    @Override
+    public void sort() {
+        Map<Boolean,List<FormData>> map = this.formDataList.stream().collect(Collectors.partitioningBy(e->e!=null&&e.getFormula().getFormula().contains("E[")));
+        this.formDataList.clear();
+        /*没有依赖的*/
+        List<FormData> simple=map.get(false);
+        if(CollectionUtil.isNotEmpty(simple)){
+            this.formDataList.addAll(simple);
+        }
+        /*有依赖的*/
+        List<FormData> rely= map.get(true);
+        if(CollectionUtil.isNotEmpty(rely)){
+            sort(rely,((rely.size()+1)/2)*rely.size());
+            this.formDataList.addAll(rely);
+        }
+//        return this;
+    }
+
+    @Override
+    public void pre() {
+        if(CollectionUtil.isNotEmpty(this.formDataList)){
+            for(FormData fd:this.formDataList){
+                /*预处理公式脚本*/
+                String tmp =fd.getFormula().getFormula();
+                tmp = tmp.replace(FC, CustomFunction.CLASS_CALL);
+                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()+"+'");
                         }
+                        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);
                 }
 
-               /*公式执行*/
-                for(FormData fd:total){
-                    Formula formula= fd.getFormula();
-                    formulaStrategyFactory.get(fd).forEach(e->e.execute(list,constantMap));
-                    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);
+                if(tmp.contains("E[")||tmp.contains("WP[")){
+                    Matcher am = AP.matcher(tmp);
+                    while (am.find()){
+                      tmp = tmp.replace(am.group(),am.group(1)+"['"+am.group(2)+"']");
+                    }
+                }
+                fd.getFormula().setFormula(tmp);
+            }
+        }
+//         return this;
+    }
 
-                                        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);
+    @Override
+    public void special() {
+        for(FormData fd:this.formDataList) {
+            formulaStrategyFactory.get(fd).forEach(e->e.execute(this.formDataList,constantMap));
+        }
+//        return this;
+    }
 
-                                        f = f.replace(CustomFunction.CLASS_CALL+m.group(),data.toString());
-                                        fd.getFormula().setFormula(f);
-                                    }
+    @Override
+    public void calculate() {
+        /*公式执行*/
+        /*先处理聚合类的方法*/
+        /*每次执行都会构造一个只有依赖的的集合*/
+        for(FormData fd:this.formDataList){
+            Formula formula= fd.getFormula();
+            if(formula!=null){
+                String f=formula.getFormula();
+                if(Func.isNotBlank(f)){
+                    Map<String, Object> currentMap = new HashMap<>(this.constantMap);
+                    List<String>  relyList = fd.getFormula().getRelyList();
+                    if(CollectionUtil.isNotEmpty(relyList)){
+                        List<FormData>  ele = this.formDataList.stream().filter(e->relyList.contains(e.getCode())).collect(Collectors.toList());
+                        if(CollectionUtil.isNotEmpty(ele)){
+                            /*每一组依赖的数据*/
+                            Map<Integer,Map<String,List<Object>>> dataSource = new HashMap<>(20);
+                            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<String,List<Object>>(20));
+                                    t.put(e.getCode(),entry.getValue().stream().map(ElementData::getValue).flatMap(o->Collections.nCopies(e.getStep(),o).stream()).collect(Collectors.toList()));
                                 }
-                                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()){
-                                                List<ElementData> eds = slice(entry.getValue(),constantMap,f,entry.getKey());
-                                                fd.setValues(eds);
-                                            }
-                                        }
+                            }
+                            if(dataSource.size()>0){
+                                for(Map.Entry<Integer,Map<String,List<Object>>> entry:dataSource.entrySet()){
+                                    if(entry.getValue().keySet().size()>=ele.size()){
+                                        List<ElementData> eds = slice(entry.getValue(),this.constantMap,f,entry.getKey());
+                                        fd.setValues(eds);
                                     }
-
-                                }else{
-                                    fd.getValues().add(new ElementData(0,0,Expression.parse(formula.getFormula()).calculate(currentMap)));
                                 }
-                            }else{
-                              fd.getValues().add(new ElementData(0,0,Expression.parse(formula.getFormula()).calculate(currentMap)));
                             }
+
+                        }else{
+                            fd.getValues().add(new ElementData(0,0,Expression.parse(formula.getFormula()).calculate(currentMap)));
                         }
+                    }else{
+                        fd.getValues().add(new ElementData(0,0,Expression.parse(formula.getFormula()).calculate(currentMap)));
                     }
                 }
             }
-        total.stream().filter(e->Func.isNotBlank(e.getFormula().getFormula())).map(FormData::getValues).forEach(e->e.stream().map(JSON::toJSONString).forEach(System.out::println));
-    }
-
-    @Override
-    public void execute(TableElementConverter tec) {
-        WbsTreeContract one = this.treeContractService.getById(tec.getTableInfoList().get(0).getPkeyId());
-        this.execute(tec.getFds(),tec.getContractId(),Func.isNotEmpty(one.getOldId())?Long.parseLong(one.getOldId()):one.getParentId());
+        }
     }
 
     public  Map<String,Object> getMap(Map<String,Object> main,String key){
@@ -226,7 +206,6 @@ 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<>();
 
@@ -264,8 +243,10 @@ 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 Pattern AP=Pattern.compile("(E|WP)\\[([^]]+)]");
+
     public static final String IF_REG= "(?<=T\\(com.mixsmart.utils.CustomFunction\\).ifelse\\()[^,]+(?=,)";
-    public static final  Pattern IF = Pattern.compile(WP_REG);
+    public static final  Pattern IF = Pattern.compile(IF_REG);
     /**
      * 依赖排序
      */
@@ -320,23 +301,29 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         }
     }
 
-/*    public static void main(String[] args) {
-        Set<Class<?>> classList =  ReflectionUtil.getClassSetBySuper(IFcHandler.class);
-        List<IFcHandler> receiptHandlerList = new ArrayList<>();
-        if (classList.size() > 0) {
-            for (Class<?> clazz : classList) {
-                try {
-                    receiptHandlerList.add((IFcHandler)clazz.newInstance());
-                } catch ( Exception e) {
-                    e.printStackTrace();
-                }
-            }
-        }
-        System.out.println();
-    }*/
 
 
 
+public void  polymerization(){
+//    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);
+//        }
+//    }
+}
+
+
 }
 
 

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

@@ -37,7 +37,7 @@ public class WbsParamServiceImpl extends BaseServiceImpl<WbsParamMapper, WbsPara
      * 文件题名*/
     public static final String FILE_TITLE="FILE_TITLE";
     @Override
-    @Cacheable(cacheNames = "file_title", key = "#nodeId+'@'+#contractId")
+    @Cacheable(cacheNames = "file_title", key = "#nodeId+'@'+#contractId+T(System).currentTimeMillis()/(1000*60)")
     public String createFileTitle(Long nodeId,Long contractId) {
         if(BaseUtils.isNotNull(nodeId,contractId)){
             StaticLog.info("获取节点{}文件题名",nodeId);