瀏覽代碼

公式相关:调整、试验公式节点公式获取问题

yangyj 1 年之前
父節點
當前提交
508ae85a62

+ 34 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/CellDataVo.java

@@ -0,0 +1,34 @@
+package org.springblade.manager.dto;
+
+import javafx.scene.control.Cell;
+import lombok.Data;
+import org.springblade.core.tool.utils.BeanUtil;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author yangyj
+ * @Date 2023/10/10 10:00
+ * @description 每个单元格的内容信息
+ */
+@Data
+public class CellDataVo {
+    private Long id;
+    private Long pageId;
+    private String tabKey;
+    private String key;
+    private Integer x;
+    private Integer y;
+    private Object value;
+
+    public void setTabKey(String tabKey) {
+        String[] a= tabKey.split("__");
+        this.key=a[0];
+        String[] b=a[1].split("_");
+        this.x=Integer.parseInt(b[1]);
+        this.y=Integer.parseInt(b[0]);
+        this.tabKey = tabKey;
+    }
+
+}

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

@@ -133,6 +133,9 @@ public class ElementData implements Serializable {
         /*同列*/
         return this.groupId + StringPool.AT + this.index + StringPool.AT + this.x;
     }
-
+    public String getCoordsKey() {
+        /*同行*/
+        return this.groupId + StringPool.AT + this.index + StringPool.AT + this.x+ StringPool.AT + this.y;
+    }
 
 }

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

@@ -15,7 +15,7 @@ import java.util.stream.Stream;
 /**
  * @author yangyj
  * @Date 2022/6/15 15:02
- * @description TODO
+ * @description 元素对象
  */
 @Data
 public class FormData {
@@ -75,7 +75,10 @@ public class FormData {
      * 当需要偏移处理的时候需要备份原数据,等计算完成还原回去
      */
     private List<ElementData> backup;
+    /**???*/
     private Map<String, ElementData> vMap = new HashMap<>();
+    /**数据库里的原始数据*/
+    private List<CellDataVo> cellDataVoList=new ArrayList<>();
     /**
      * 公式id
      */
@@ -92,7 +95,7 @@ public class FormData {
     /**
      * 存储元素对应的表记录表Id
      */
-    private List<String> tableIds;
+    private List<Long> tableIds;
 
     private String position;
     /**
@@ -107,6 +110,8 @@ public class FormData {
      * 是否完成执行
      */
     private Boolean finished = false;
+    /**是否已经初始化好数据*/
+    private Boolean initReady=false;
     /**
      * 元素和单元格的映射信息
      */
@@ -115,6 +120,10 @@ public class FormData {
      * 是否是当前节点的执行元素
      */
     public Boolean isCurrentNodeElement = false;
+    /**
+     * 是否是当前提交的执行元素
+     */
+    public Boolean isCurrentSubmitElement = false;
     public static final String CODE_REG = "[^:]+:[^:]+";
 
     /**
@@ -169,14 +178,16 @@ public class FormData {
         flushCoords(coords);
     }
 
+    /**哈希表*/
     public void flushVmap() {
         if (Func.isNotEmpty(this.values)) {
             this.values.forEach(v -> {
-                vMap.put(v.getRowKey(), v);
+                vMap.put(v.getCoordsKey(), v);
             });
         }
     }
 
+    /**绑定单元格信息*/
     public void flushCoords(String coords) {
         if (Func.isNotBlank(coords)) {
             this.coordsList = Stream.of(coords).flatMap(e -> Arrays.stream(e.split(";"))).map(e -> {

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

@@ -0,0 +1,21 @@
+package org.springblade.manager.dto;
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author yangyj
+ * @Date 2023/10/9 14:21
+ * @description 工具类,用来刷treeCode
+ */
+@Data
+public class TreeNode<T> {
+       private Long id;
+       private Long parentId;
+       private T value;
+       private List<T> children=new ArrayList<>();
+       public boolean hasChildren(){
+          return !children.isEmpty();
+       }
+}

+ 35 - 1
blade-service/blade-manager/src/main/java/com/mixsmart/utils/FormulaUtils.java

@@ -32,6 +32,7 @@ import org.springblade.manager.dto.ElementData;
 import org.springblade.manager.dto.FormData;
 import org.springblade.manager.dto.LocalVariable;
 import org.springblade.manager.entity.Formula;
+import org.springblade.manager.formula.NodeTable;
 import org.springblade.manager.utils.FileUtils;
 
 import java.awt.*;
@@ -742,8 +743,41 @@ public class FormulaUtils {
         }
         return result.toString();
     }
+    /**最大循环次数*/
+    public static int MAX_LOOP=20;
+    /**
+     * @Description 当前提交表单数据公式执行最小影响元素范围
+     * @Param [curTableNames:当前提交页面对应表编号, processFds:当前工序包含的所有元素]
+     * @Author yangyj
+     * @Date 2023.10.09 15:26
+     **/
+public static List<FormData>  registerFd(List<String> curTableNames, List<FormData> processFds){
+        Map<Boolean,List<FormData>> group = processFds.stream().collect(Collectors.partitioningBy(e->curTableNames.contains(e.getTableName())));
+        List<FormData> curFormDatas =group.get(true);
+        List<FormData> other=group.get(false);
+        List<FormData> curFormDatasAdd;
+        int loop=0;
+        do{
+            loop++;
+            Set<String> codeSet= curFormDatas.stream().map(FormData::getCode).collect(Collectors.toSet());
+            Map<Boolean,List<FormData>> groupTmp = other.stream().collect(Collectors.partitioningBy(e->codeSet.contains(e.getCode())));
+             curFormDatasAdd=groupTmp.get(true);
+            if(curFormDatasAdd.isEmpty()){
+                loop=MAX_LOOP;
+            }else{
+                curFormDatas.addAll(curFormDatasAdd);
+            }
+            other=groupTmp.get(false);
+            /*无元素可添加或者没有添加新的元素或者循环次数超过20则结束*/
+        }while (!other.isEmpty()&&loop<MAX_LOOP);
+        return curFormDatas;
+}
 
-
+/**最小加载页面*/
+public static Map<String,List<Long>> relatedPages(List<FormData> curFormDatas ,List<NodeTable> tableAll){
+   Set<String> initTableNames= curFormDatas.stream().map(FormData::getTableName).collect(Collectors.toSet());
+   return tableAll.stream().filter(e->initTableNames.contains(e.getInitTableName())).collect(Collectors.groupingBy(NodeTable::getInitTableName,Collectors.mapping(NodeTable::getPKeyId,Collectors.toList())));
+}
 
 
 

+ 120 - 27
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/TableElementConverter.java

@@ -2,6 +2,7 @@ package org.springblade.manager.formula.impl;
 
 
 import cn.hutool.log.StaticLog;
+import com.alibaba.fastjson.JSONArray;
 import com.mixsmart.utils.FormulaUtils;
 import com.mixsmart.utils.StringUtils;
 import lombok.Data;
@@ -10,6 +11,7 @@ import org.springblade.common.utils.BaseUtils;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.StringPool;
 import org.springblade.manager.bean.TableInfo;
+import org.springblade.manager.dto.CellDataVo;
 import org.springblade.manager.dto.ElementData;
 import org.springblade.manager.dto.FormData;
 import org.springblade.manager.entity.Formula;
@@ -21,11 +23,13 @@ import org.springblade.manager.formula.KeyMapper;
 import org.springblade.manager.formula.NodeTable;
 import org.springblade.manager.vo.AppWbsTreeContractVO;
 import org.springblade.manager.vo.CurrentNode;
+import org.springframework.beans.BeanUtils;
 
 import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 import java.util.stream.Stream;
 
 /**
@@ -48,24 +52,22 @@ public class TableElementConverter implements ITableElementConverter {
     List<KeyMapper> keyMappers;
     List<Formula> formulas;
     Map<Long, Formula> formulaMap = new HashMap<>();
+   /* List<FormData> fds = new ArrayList<>();*/
     /**
-     * 公式执行时的元素对象
-     */
-    List<FormData> fds = new ArrayList<>();
-    /**
-     * 所有元素数据集
+     * 所有已经初始化数据的元素集
      */
     public Map<String, FormData> formDataMap = new HashMap<>();
+
+    /**当前工序所有元素信息*/
+    public Map<String, FormData> formDataNodeMap = new HashMap<>();
     /**
      * {tableName:{key:val}}
      */
     Map<String, Map<String, String>> coordinateMap = new HashMap<>();
+    /**业务表所包含的所有页面,根据表名查询*/
+    Map<String,List<Long>> tableNamePkeyIdMap;
     /**表单对应的Excel对象*/
     public Map<String, Workbook> wkbMap = new HashMap<>();
-    /**
-     * {code:List<ElementData>}
-     */
-    Map<String, ElementData> elementDataMap = new HashMap<>();
     /**
      * 跨表数据
      */
@@ -87,7 +89,7 @@ public class TableElementConverter implements ITableElementConverter {
      */
     public Map<String, Object> constantMap = new HashMap<>();
     /**公式执行序列*/
-    public List<FormData> formDataList;
+    public List<FormData> formDataList= new ArrayList<>();
 
     /**检查项*/
     public List<FormData> checkItems = new ArrayList<>();
@@ -109,8 +111,20 @@ public class TableElementConverter implements ITableElementConverter {
 
     /*优化测试新增属性start*/
 
-    public TableElementConverter(List<FormData>curFormDatas,List<FormData> processFds, Map<String, Map<String, String>> coordinateMap, CurrentNode wtc, List<NodeTable> tableAll) {
+    public TableElementConverter(List<TableInfo> tableInfoList,List<FormData>curFormDatas,List<FormData> processFds,Map<String,List<Long>> tableNamePkeyIdMap, Map<String, Map<String, String>> coordinateMap, CurrentNode wtc, List<NodeTable> tableAll) {
+        for(FormData fd:processFds){
+            fd.setIsCurrentNodeElement(true);
+            formDataNodeMap.put(fd.getCode(),fd);
+        }
+        this.tableInfoList=tableInfoList;
+        this.formDataList=curFormDatas;
+        for(FormData fd:curFormDatas){
+            /*设置为当前提交元素*/
+            fd.setIsCurrentSubmitElement(true);
+            formDataMap.put(fd.getCode(),fd);
+        }
         this.coordinateMap = coordinateMap;
+        this.tableNamePkeyIdMap=tableNamePkeyIdMap;
         this.nodeId = wtc.getPkId();
         this.wbsTreeId = wtc.getId();
         this.currentNode = wtc;
@@ -204,12 +218,43 @@ public class TableElementConverter implements ITableElementConverter {
                 this.formDataMap.put(fd.getCode(), fd);
                 if (fd.getFormula() != null) {
                     /*只有需要执行公式的才放这里*/
-                    this.fds.add(fd);
+                    this.formDataList.add(fd);
                 }
             });
         }
     }
+    public void before2(){
+           for(FormData fd:this.formDataList){
+               /*根据单元格信息、表单页对象、单元格原始数据 初始化袁术数据*/
+               try {
+                   fd.setIsCurrentNodeElement(Boolean.TRUE);
+                   String coords =this.coordinateMap.getOrDefault(fd.getTableName(), new HashMap<>()).get(fd.getKey());
+                   if(Func.isNotBlank(coords)){
+                       fd.flushCoords(coords);
+                   }else{
+                       log.put(FormulaLog.POSITION,fd.getCode()+"("+fd.getEName()+")");
+                       continue;
+                   }
+                   List<Long> pkeyIds= this.tableNamePkeyIdMap.get(fd.getTableName());
+                   List<Coords> coordsList= fd.getCoordsList();
+                   List<ElementData> eds =fd.getValues();
+                   Map<String,Object> map = fd.getCellDataVoList().stream().collect(Collectors.toMap(e-> StringUtils.join( pkeyIds.indexOf(e.getPageId()), e.getX(), e.getY(), StringPool.AT), CellDataVo::getValue));
+                   for(int i=0;i<pkeyIds.size();i++){
+                       for(Coords c:coordsList){
+                           String k=StringUtils.join( i, c.getX(), c.getY(), StringPool.AT);
+                           eds.add(new ElementData(i,0,map.get(k),c.getX(),c.getY()));
+                       }
+                   }
+                   /*数据初始化加载*/
+                   fd.setInitReady(true);
+                   /*备份原始数据,用于更新比较*/
+                   fd.init();
+               }catch (Exception e){
+                   log.put(FormulaLog.POSITION,fd.getCode()+"("+fd.getEName()+")");
+               }
 
+           }
+    }
 
     @Override
     public void after() {
@@ -248,25 +293,71 @@ public class TableElementConverter implements ITableElementConverter {
         }
 
     }
+    public void after2(){
+        List<FormData> updateList = this.formDataMap.values().stream().filter(e -> e.getUpdate() == 1 && e.isCurrentNodeElement).collect(Collectors.toList());
+        if(!updateList.isEmpty()){
+             List<Long> pkeyIds= this.tableNamePkeyIdMap.values().stream().flatMap(Collection::stream).collect(Collectors.toList());
+             Map<String,List<FormData>> group = updateList.stream().collect(Collectors.groupingBy(FormData::getTableName,Collectors.toList()));
+             Map<String,TableInfo> tableInfoMap= this.tableInfoList.stream().collect(Collectors.toMap(TableInfo::getPkeyId,t->t));
+            TableInfo one = this.tableInfoList.get(0);
+             for(Long pi:pkeyIds){
+                 if(!tableInfoMap.containsKey(pi.toString())){
+                     TableInfo info=new TableInfo();
+                     BeanUtils.copyProperties(one,info);
+                     info.setPkeyId(pi.toString());
+                     info.setDataMap(new LinkedHashMap<>());
+                     tableInfoMap.put(pi.toString(),info);
+                 }
+             }
+             group.forEach((k,v)->{
+                   /*k:表名,v:表单页集合*/
+                 for(FormData fd:v){
+                     /*LinkedHashMap<Integer, List<ElementData>> pages = fd.getValues().stream().collect(Collectors.groupingBy(ElementData::getIndex, LinkedHashMap::new, Collectors.toList()));*/
+                     List<List<ElementData>> pages= BaseUtils.splitList( fd.getValues(),fd.getCoordsList().size());
+                     List<Long> ids = this.tableNamePkeyIdMap.get(k);
+                     for(int i=0;i<ids.size();i++){
+                         Long id=ids.get(i);
+                         TableInfo info = tableInfoMap.get(id.toString());
+                         List<ElementData> p = pages.get(i);
+                         info.setToBeUpdated(true);
+                         info.getDataMap().put(fd.getKey(), recovery(p));
+                     }
+                 }
 
+             });
+        }else {
+            log.put(FormulaLog.OTHER,"公式未插入或者修改任何数据");
+        }
+    }
     /**
      * 备份
      */
+/*
     public void afterBak() {
-        /*可以优化对每一张表进行元素分类,同一张元素*/
-        /*根据数据库表分组*/
+        */
+/*可以优化对每一张表进行元素分类,同一张元素*//*
+
+        */
+/*根据数据库表分组*//*
+
         LinkedHashMap<String, List<KeyMapper>> tabs = keyMappers.stream().collect(Collectors.groupingBy(KeyMapper::getCode, LinkedHashMap::new, Collectors.toList()));
         Map<String, List<TableInfo>> tableMap = new HashMap<>(tabs.size() * 2);
-        for (FormData fd : this.fds) {
+        for (FormData fd : this.formDataList) {
             if (fd.getUpdate().equals(0)) {
                 continue;
             }
-            /*暂时不处理没有公式配置的数据*/
-            /*元素所有的数据内容*/
+            */
+/*暂时不处理没有公式配置的数据*//*
+
+            */
+/*元素所有的数据内容*//*
+
             List<ElementData> values = fd.getValues();
             List<TableInfo> tables;
             LinkedHashMap<Integer, LinkedHashMap<Integer, List<ElementData>>> groups = values.stream().collect(Collectors.groupingBy(ElementData::getGroupId, LinkedHashMap<Integer, LinkedHashMap<Integer, List<ElementData>>>::new, Collectors.groupingBy(ElementData::getIndex, LinkedHashMap<Integer, List<ElementData>>::new, Collectors.toList())));
-            /*每个元素数据有N组组成,每组由N页组成*/
+            */
+/*每个元素数据有N组组成,每组由N页组成*//*
+
             if (tableMap.containsKey(fd.getTableName())) {
                 tables = tableMap.get(fd.getTableName());
             } else {
@@ -278,7 +369,9 @@ public class TableElementConverter implements ITableElementConverter {
                 group.forEach((index, page) -> {
                     if (Func.isNotEmpty(page)) {
                         TableInfo info = tables.get(index);
-                        /*每一页对应一个info*/
+                        */
+/*每一页对应一个info*//*
+
                         info.getDataMap().put(fd.getKey(), recovery(page, fd));
                     }
                 });
@@ -287,12 +380,12 @@ public class TableElementConverter implements ITableElementConverter {
         }
 
     }
+*/
 
     /**
      * 格式化回写内容
      */
-    @Deprecated
-    public String recovery(List<ElementData> dataList, String position, String z) {
+/*    public String recovery(List<ElementData> dataList, String position, String z) {
         List<Coords> coordsList = CoordsBuilder.getInstance().build(position);
         StringBuilder sb = new StringBuilder();
         List<Integer[]> total = new ArrayList<>();
@@ -314,7 +407,7 @@ public class TableElementConverter implements ITableElementConverter {
             for (int i = outer; i < outer2; i++) {
                 for (int j = inner; j < inner2; j++) {
                     if (coords.getHorizontal()) {
-                        /*[x,y]*/
+                        *//*[x,y]*//*
                         indexs.add(new Integer[]{j, i});
                     } else {
                         indexs.add(new Integer[]{i, j});
@@ -332,14 +425,14 @@ public class TableElementConverter implements ITableElementConverter {
             }
             ElementData d = dataList.get(i);
             Integer[] a = total.get(i);
-            /*a:[x,y]*/
+            *//*a:[x,y]*//*
             sb.append(a[1]).append(StringPool.UNDERSCORE).append(a[0]).append(StringPool.UNDERSCORE).append(d.stringValue());
         }
         return sb.toString();
-    }
+    }*/
 
-    @Deprecated
-    public String recovery(List<ElementData> dataList, FormData fd) {
+
+   /* public String recovery(List<ElementData> dataList, FormData fd) {
         String coords = this.coordinateMap.get(fd.getTableName()).get(fd.getKey());
         StringBuilder sb = new StringBuilder();
         if (Func.isNotEmpty(coords)) {
@@ -359,7 +452,7 @@ public class TableElementConverter implements ITableElementConverter {
             }
         }
         return sb.toString();
-    }
+    }*/
 
     public String recovery(List<ElementData> dataList) {
         if (Func.isNotEmpty(dataList)) {

+ 38 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/service/IFormulaService.java

@@ -19,6 +19,8 @@ import java.util.Map;
 public interface IFormulaService extends BaseService<Formula> {
 
     void execute(TableElementConverter tec);
+    void execute2(TableElementConverter tec);
+
 
     /**
      * 变量准备
@@ -49,6 +51,35 @@ public interface IFormulaService extends BaseService<Formula> {
      * 格式化
      */
     void format();
+    /**
+     * 变量准备
+     */
+    IFormulaService init2();
+
+    /**
+     * 依赖排序
+     */
+    /*IFormulaService sort2();*/
+
+    /**
+     * 公式预处理
+     */
+    /*IFormulaService pre2();*/
+
+    /**
+     * 特殊公式处理
+     */
+    /*IFormulaService special2();*/
+
+    /**
+     * 公式运算
+     */
+    /*IFormulaService calculate2();*/
+
+    /**
+     * 格式化
+     */
+    /*void format2();*/
 
     List<Formula> getFormulaList(List<KeyMapper> keyMapperList);
     /**
@@ -58,9 +89,12 @@ public interface IFormulaService extends BaseService<Formula> {
 
    void formulaInto(List<FormData> curFormDatas, String projectId, String nodeId, ExecuteType executeType);
 
-
+    /**根据元素码获取元素信息*/
     Map<String, Object> getElementInfoByCodes(String codes);
-
+    /**通过元素码创建FormData*/
+    Map<String, FormData> createFormDataByCode(String codes);
+    /**通过表编号创建FormData*/
+    List<FormData> createFormDataByTableName(String tableNames);
     /**根据wbs_tree_contract 的pkeyId查询项目级对应节点*/
      WbsTreePrivate wtpId(Long pkeyId);
     /**根据wbs_tree_private的pkeyId获取公共树*/
@@ -69,5 +103,7 @@ public interface IFormulaService extends BaseService<Formula> {
     <T> T getSqlOne(@NotNull  String sql,@NotNull Class<T> clazz , Object ...args);
     <T> List<T> getSqlList(@NotNull String sql, @NotNull Class<T> clazz,Object... args);
 
+    void loadElementData(List<FormData> curFormDatas,Map<String,List<Long>>  tableNamePkeyIdMap);
+
 
 }

+ 15 - 23
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java

@@ -61,7 +61,6 @@ import org.springblade.manager.enums.ExecuteType;
 import org.springblade.manager.formula.FormulaLog;
 import org.springblade.manager.formula.KeyMapper;
 import org.springblade.manager.formula.NodeTable;
-import org.springblade.manager.formula.impl.ElementConverter;
 import org.springblade.manager.formula.impl.TableElementConverter;
 import org.springblade.manager.mapper.ExcelTabMapper;
 import org.springblade.manager.service.*;
@@ -405,60 +404,53 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                List<NodeTable> tableAll = createNodeTables(nodeId, tableInfoList.get(0).getContractId(), tableInfoList.get(0).getProjectId(), type);
                String tableNames=tableAll.stream().map(NodeTable::getInitTableName).distinct().collect(Collectors.joining("','","'","'"));
                /*当前工序包含的所有元素信息,还未包含数据*/
-               List<FormData>  processFds =this.formulaService.getSqlList(
-                                           "select d.id,c.tab_ch_name tableChName,d.e_type eType,d.e_name eName,d.e_length eLength,d.e_allow_deviation eAllowDeviation,CONCAT(c.tab_en_name,':',d.e_key) code from m_table_info c join m_wbs_form_element d  on  c.id=d.f_id where d.is_deleted=0 and c.tab_en_name in("+tableNames+")"
-                                           ,FormData.class
-                                   );
+               List<FormData>  processFds =this.formulaService.createFormDataByTableName(tableNames);
                List<Long> pkeyIds =tableInfoList.stream().map(TableInfo::getPkeyId).map(Long::parseLong).collect(Collectors.toList());
                List<String> curTableNames=tableAll.stream().filter(e->pkeyIds.contains(e.getPKeyId())).map(NodeTable::getInitTableName).collect(Collectors.toList());
-               List<NodeTable> curNodeTables=tableAll.stream().filter(e->curTableNames.contains(e.getInitTableName())).collect(Collectors.toList());
-               /*当前提交的元素*/
-               List<FormData> curFormDatas=processFds.stream().filter(e->curTableNames.contains(e.getTableName())).collect(Collectors.toList());
+              /* List<NodeTable> curNodeTables=tableAll.stream().filter(e->curTableNames.contains(e.getInitTableName())).collect(Collectors.toList());*/
               /*嵌入公式*/
-              this.formulaService.formulaInto(curFormDatas,tableInfoList.get(0).getProjectId(), String.valueOf(nodeId), type);
+              this.formulaService.formulaInto(processFds,tableInfoList.get(0).getProjectId(), String.valueOf(nodeId), type);
               // List<KeyMapper> keyMappers = this.formulaService.getKeyMapperList(tableAll.stream().map(NodeTable::getPKeyId).filter(Func::isNotEmpty).collect(Collectors.toList()), tableInfoList.get(0).getProjectId(), String.valueOf(nodeId), type);
                if (Func.isNotEmpty(tableAll)) {
-                   Map<String, Map<String, String>> coordinateMap = createCoordinateMap2(pkeyIds, type);
                    //List<Formula> formulas = this.formulaService.getFormulaList(keyMappers);
                    /*要找到最小加载数量
                    * 1.根据依赖溯源然后确定当前页面修改数据的影响范围
                    * 2.区分能部分执行和必须整体执行公式的元素*/
-                   List<FormData> relyFds=  curFormDatas.stream().filter(e->e.getFormula()!=null&&e.getFormula().getRelyList()!=null).collect(Collectors.toList());
-
+                  /* List<FormData> relyFds=  curFormDatas.stream().filter(e->e.getFormula()!=null&&e.getFormula().getRelyList()!=null).collect(Collectors.toList());*/
+                   /*当前提交的元素*/
+                   List<FormData> curFormDatas=FormulaUtils.registerFd(curTableNames,processFds);
+                   /*最小加载页面*/
+                   Map<String,List<Long>> tableNamePkeyIdMap =FormulaUtils.relatedPages(curFormDatas,tableAll);
+                   /*加载单元格信息*/
+                   Map<String, Map<String, String>> coordinateMap = createCoordinateMap2(tableNamePkeyIdMap.values().stream().flatMap(Collection::stream).collect(Collectors.toList()), type);
+                   this.formulaService.loadElementData(curFormDatas,tableNamePkeyIdMap);
                    /*判断哪些元素是可部分执行和整体执行*/
                    CurrentNode currentNode = null;
-                   Long pKeyId = null;
                    Long contractId = null;
                    Long projectId = null;
                    if (type.equals(ExecuteType.INSPECTION)) {
                        WbsTreeContract wtc = this.wbsTreeContractService.getOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getPKeyId, nodeId));
-                       pKeyId = wtc.getPKeyId();
                        currentNode = createCurrentNode(wtc);
                        contractId = Long.parseLong(wtc.getContractId());
                        projectId = Long.parseLong(wtc.getProjectId());
                    } else if (type.equals(ExecuteType.TESTING)) {
                        WbsTreePrivate wtp = this.wbsTreePrivateService.getOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getPKeyId, nodeId));
-                       pKeyId = wtp.getPKeyId();
                        currentNode = createCurrentNode(wtp);
                        projectId = Long.parseLong(wtp.getProjectId());
                    }
                    if (currentNode != null) {
-                       TableElementConverter tec = new TableElementConverter(curFormDatas, processFds, coordinateMap, currentNode, tableAll);
+                       TableElementConverter tec = new TableElementConverter(tableInfoList,curFormDatas, processFds, tableNamePkeyIdMap,coordinateMap, currentNode, tableAll);
                        tec.setLog(log);
                        tec.setExecuteType(type);
                        tec.setContractId(contractId);
                        tec.setProjectId(projectId);
                        if (tec.isPresent()) {
-                           tec.before();
-                           this.formulaService.execute(tec);
-                           tec.after();
+                           tec.before2();
+                           this.formulaService.execute2(tec);
+                           tec.after2();
                        } else {
                            tec.getLog().put(FormulaLog.OTHER, "没有执行任何公式");
                        }
-                       long totalTime = stopWatch.getTotalTimeMillis();
-                       log.put(FormulaLog.PF, "公式执行消耗时间:" + (double)totalTime / 1000 + "秒");
-                       StaticLog.info("公式执行用时:{}", totalTime);
-                       updateFormulaLog(log.toJsonString(), pKeyId);
                    }
                }
                stopWatch.stop();

+ 206 - 47
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java

@@ -15,7 +15,6 @@ import org.apache.poi.ss.usermodel.*;
 import org.springblade.common.utils.BaseUtils;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.utils.SnowFlakeUtil;
-import org.springblade.core.mp.base.BaseEntity;
 import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.*;
@@ -88,6 +87,9 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     /**公式参数*/
     public final static String FMOT="OP";
 
+    /**是否使用新流程*/
+    public final static  boolean isNew=false;
+
 
 
 
@@ -99,6 +101,13 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         this.init().sort().pre().special().calculate().format();
     }
 
+    @Override
+    public void execute2(TableElementConverter tec) {
+        this.tec=tec;
+        /*初始化变量>>依赖排序>>预处理>>特殊公式>>通用公式执行>>数据格式化*/
+        this.init2().sort().pre().special().calculate().format();
+    }
+
     @Override
     public IFormulaService init() {
         /*基础数据*/
@@ -113,6 +122,20 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         }
         return this;
     }
+    @Override
+    public IFormulaService init2(){
+        /*基础数据*/
+        baseData();
+        if(ExecuteType.INSPECTION.equals(tec.getExecuteType())) {
+            /*依赖加载*/
+            checkingMissingList();
+            /*公式参数*/
+            option();
+            /*评定表*/
+            assessmentForm();
+        }
+        return this;
+    }
 
     public  void option(){
             FormulaOption formulaOption = this.formulaOptionService.getById(tec.getCurrentNode().getPkId());
@@ -121,20 +144,14 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
             }
     }
 
-/*    public void textInfo(){
-            List<Map<String,Object>>  textInfoMap= this.jdbcTemplate.queryForList("SELECT b.tab_id pkId,b.col_name val ,CONCAT(a.init_table_name,':',b.col_key)code from m_wbs_tree_contract a inner join m_textdict_info b on a.p_key_id=b.tab_id   " +
-                    "where a.p_key_id in("+this.tec.getTableAll().stream().map(NodeTable::getPKeyId).map(Func::toStr).collect(Collectors.joining(","))+") and b.type=8 ");
-            if(Func.isNotEmpty(textInfoMap)){
-                Map<String,List<Map<String,Object>>> tmap = textInfoMap.stream().collect(Collectors.groupingBy(m->m.get("code").toString()));
-                tec.constantMap.put(TEXT_INFO_MAP,tmap);
-            }
-    }*/
+
 
 
     public void baseData(){
-        List<FormData> list =this.tec.getFds();
+        /*List<FormData> list =this.tec.getFds();*/
         CurrentNode one=this.tec.getCurrentNode();
-        tec.formDataList=list;
+        /*tec.formDataList=list;*/
+        /*预设关键字*/
         keyWord(tec.constantMap);
 
         /*wbs节点链*/
@@ -158,25 +175,42 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
 
 
 
-    /**补充确实的原始依赖*/
+    /**补充缺失的元素依赖*/
    public void checkingMissingList(){
        List<String> missingList = new ArrayList<>();
-       tec.formDataList.forEach(fd->{
-           if(fd.executable()){
-               relyParse(fd.getFormula());
-               Formula f= fd.getFormula();
-               List<String> relyList=f.getRelyList();
-               if(Func.isNotEmpty(relyList)){
-                   relyList.forEach(r->{
-                       if(tec.formDataMap.values().stream().map(FormData::getCode).noneMatch(k->StringUtils.isEquals(k,r))){
-                           missingList.add(r);
-                       }
-                   });
+       if(isNew){
+           tec.formDataList.forEach(fd->{
+               if (fd.executable()) {
+                   relyParse(fd.getFormula());
+                   Formula f = fd.getFormula();
+                   List<String> relyList = f.getRelyList();
+                   if (Func.isNotEmpty(relyList)) {
+                       relyList.forEach(r -> {
+                           if (!tec.formDataMap.containsKey(r)) {
+                               missingList.add(r);
+                           }
+                       });
+                   }
                }
-           }
-       });
-
-       missingFill(missingList);
+           });
+           missingFill2(missingList);
+       }else {
+           tec.formDataList.forEach(fd -> {
+               if (fd.executable()) {
+                   relyParse(fd.getFormula());
+                   Formula f = fd.getFormula();
+                   List<String> relyList = f.getRelyList();
+                   if (Func.isNotEmpty(relyList)) {
+                       relyList.forEach(r -> {
+                           if (tec.formDataMap.values().stream().map(FormData::getCode).noneMatch(k -> StringUtils.isEquals(k, r))) {
+                               missingList.add(r);
+                           }
+                       });
+                   }
+               }
+           });
+           missingFill(missingList);
+       }
        if(Func.isNotEmpty(missingList)){
            StringBuilder sb = new StringBuilder();
            missingList.stream().collect(Collectors.groupingBy(s->s.split(StringPool.COLON)[0])).forEach((k,v)->{
@@ -187,6 +221,8 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     }
 
 
+
+
     public  FormulaDataBlock findFdb(){
         /*查找第一个包含分项评定子节点的父节点*/
         Long ancestor=findFirstParentId();
@@ -412,6 +448,62 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
             }
         }
     }
+    public void missingFill2(List<String> missingList){
+        /*数据池里面没有任何元素匹配和当前依赖匹配*/
+        if(Func.isNotEmpty(missingList)){
+            StaticLog.info("需要挂载的元素{}", String.join(";", missingList));
+           // Map<String, Object> elementInfoMap=this.getElementInfoByCodes(String.join(",",missingList));
+            Map<String,FormData> fdsMap = this.createFormDataByCode(String.join(",",missingList));
+            /*1从当前节点其它表格中查找匹配的元素*/
+            List<String> removeList=new ArrayList<>();
+            for (String r : missingList) {
+                String tn = r.substring(0, r.indexOf(StringPool.COLON));
+                String key = r.substring(r.indexOf(StringPool.COLON) + 1);
+                FormData fd=  fdsMap.get(r);
+             /*   if (tec.getTableAll().stream().anyMatch(e->StringUtils.isEquals(e.getInitTableName(),fd.getTableName()))) {
+                    removeList.add(r);
+                    String tableName = fd.getTableName();
+                    if (!tec.getCoordinateMap().containsKey(tableName)) {
+                        tec.getCoordinateMap().put(tableName, FormulaUtils.getElementCell());
+                    }
+                    List<Map<String, Object>> tableDatas = this.jdbcTemplate.queryForList("select * from " + tableName + " where p_key_id in(" + nodeList.stream().map(NodeTable::getPKeyId).map(StringUtils::handleNull).collect(Collectors.joining(",")) + ")");
+                    fill(tableDatas, removeList, tn, key, StringUtils.handleNull(elementInfo.get("ename")));
+                }*/
+            }
+            if (Func.isNotEmpty(removeList)) {
+                    /*移除已经找到的元素数据*/
+                missingList.removeIf(removeList::contains);
+            }
+            if(Func.isNotEmpty(missingList)){
+                /*2从当前节点的兄弟节点中查找匹配的元素*/
+                CurrentNode currentNode = tec.getCurrentNode();
+                List<Map<String,Object>> tableNamePkIdsMaps= this.jdbcTemplate.queryForList("select c.init_table_name tableName,c.p_key_id pkId,c.html_url url from (select b.id from m_wbs_tree_contract a join m_wbs_tree_contract b on (a.contract_id=b.contract_id and b.ancestors like CONCAT(a.ancestors,'%')) where a.p_key_id="+currentNode.getPkId()+" and b.is_deleted=0 and b.node_type=6 ORDER BY b.sort) k join m_wbs_tree_contract c on c.parent_id = k.id where  c.contract_id="+tec.getContractId()+" and c.is_deleted=0 ");
+                if(Func.isNotEmpty(tableNamePkIdsMaps)){
+                    // removeList.clear();
+                    missingList.forEach(miss->{
+                      /*  Map<String,Object> elementInfo= (Map<String, Object>) elementInfoMap.get(miss);
+                        String tn = miss.substring(0,miss.indexOf(StringPool.COLON));
+                        String key =miss.substring(miss.indexOf(StringPool.COLON)+1);
+                        String targetIds=tableNamePkIdsMaps.stream().filter(m->StringUtils.isEquals(m.get("tableName"),tn)).map(m->m.get("pkId")).map(StringUtils::handleNull).collect(Collectors.joining(","));
+                        if(Func.isNotEmpty(targetIds)){
+                            if(!this.tec.getCoordinateMap().containsKey(tn)){
+                                tableNamePkIdsMaps.stream().filter(m->StringUtils.isEquals(m.get("tableName"),tn)).findAny().ifPresent(m->{
+                                    this.tec.getCoordinateMap().put(tn,FormulaUtils.getElementCell(StringUtils.handleNull(m.get("url"))));
+                                });
+                            }
+                            List<Map<String,Object>> tableDatas= this.jdbcTemplate.queryForList("select * from "+tn+" where p_key_id in ("+targetIds+")");
+                            String tmp =elementInfo==null?"":StringUtils.handleNull(elementInfo.get("ename"));
+                            fill(tableDatas,removeList,tn,key,tmp);
+                        }*/
+                    });
+                }
+            }
+            if(Func.isNotEmpty(removeList)){
+                /*移除已经找到的元素数据*/
+                missingList.removeIf(removeList::contains);
+            }
+        }
+    }
 
     public void fill(List<Map<String,Object>> tableDatas,List<String> removeList,String tn,String key,String name){
         if(Func.isNotEmpty(tableDatas)){
@@ -514,28 +606,54 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         }
         this.tec.getLog().put(FormulaLog.PARAM,result.entrySet().stream().map(p->logMap.get(p.getKey())+":"+p.getValue()).collect(Collectors.joining(";")));
         /*元素动态绑定*/
+        /*绑定节点参数公式*/
+        this.bindParamFormula(total);
+        return result;
+    }
+
+    public void bindParamFormula(List<WbsParam> total){
         Map<String,Formula> formulaIdMap = this.wpService.formulaKeyMap(total.stream().map(WbsParam::getK).collect(Collectors.toList()));
-        /**查找无绑定公式且单元格只有一个的当前表单元素*/
-        List<FormData> notFormulaFds=tec.formDataMap.values().stream().filter(e->e.getIsCurrentNodeElement()&&e.getFormula()==null&&e.getCoordsList().size()==1).collect(Collectors.toList());
-        if(notFormulaFds.size()>0){
-            notFormulaFds.forEach(e->{
-                /*执行列表里不存在,且元素的名称和节点参数名称匹配成功,暂时用参数名称是否包含元素名称作为匹配规则*/
-                total.stream().filter(p->e.getEName().contains(p.getName().replaceAll("【[\\u4E00-\\u9FFF]+】|\\s+",""))&&!tec.formDataList.contains(e)).findAny().ifPresent(d->{
-                    Formula tf= formulaIdMap.get(d.getK());
-                    if(tf!=null&&e.getId()!=null) {
-                        e.setFormula(tf);
-                        tec.formDataList.add(e);
-                        ElementFormulaMapping efm = new ElementFormulaMapping();
-                        efm.setScope(FormulaBean.PARAM);
-                        efm.setParamId(d.getId());
-                        efm.setElementId(e.getId());
-                        efm.setFormulaId(tf.getId());
-                        this.elementFormulaMappingService.save(efm);
-                    }
+        /*查找无绑定公式且单元格只有一个的当前表单元素*/
+        if(isNew){
+            List<FormData> notFormulaFds=  tec.formDataList.stream().filter(e->e.getIsCurrentSubmitElement()&&e.getFormula()==null&&e.getCoordsList().size()==1).collect(Collectors.toList());
+            if(notFormulaFds.size()>0){
+                notFormulaFds.forEach(e->{
+                    /*执行列表里不存在,且元素的名称和节点参数名称匹配成功,暂时用参数名称是否包含元素名称作为匹配规则*/
+                    total.stream().filter(p->e.getEName().contains(p.getName().replaceAll("【[\\u4E00-\\u9FFF]+】|\\s+",""))&&!tec.formDataList.contains(e)).findAny().ifPresent(d->{
+                        Formula tf= formulaIdMap.get(d.getK());
+                        if(tf!=null&&e.getId()!=null) {
+                            e.setFormula(tf);
+                            ElementFormulaMapping efm = new ElementFormulaMapping();
+                            efm.setScope(FormulaBean.PARAM);
+                            efm.setParamId(d.getId());
+                            efm.setElementId(e.getId());
+                            efm.setFormulaId(tf.getId());
+                            this.elementFormulaMappingService.save(efm);
+                        }
+                    });
                 });
-            });
+            }
+        }else{
+            List<FormData> notFormulaFds=tec.formDataMap.values().stream().filter(e->e.getIsCurrentNodeElement()&&e.getFormula()==null&&e.getCoordsList().size()==1).collect(Collectors.toList());
+            if(notFormulaFds.size()>0){
+                notFormulaFds.forEach(e->{
+                    /*执行列表里不存在,且元素的名称和节点参数名称匹配成功,暂时用参数名称是否包含元素名称作为匹配规则*/
+                    total.stream().filter(p->e.getEName().contains(p.getName().replaceAll("【[\\u4E00-\\u9FFF]+】|\\s+",""))&&!tec.formDataList.contains(e)).findAny().ifPresent(d->{
+                        Formula tf= formulaIdMap.get(d.getK());
+                        if(tf!=null&&e.getId()!=null) {
+                            e.setFormula(tf);
+                            tec.formDataList.add(e);
+                            ElementFormulaMapping efm = new ElementFormulaMapping();
+                            efm.setScope(FormulaBean.PARAM);
+                            efm.setParamId(d.getId());
+                            efm.setElementId(e.getId());
+                            efm.setFormulaId(tf.getId());
+                            this.elementFormulaMappingService.save(efm);
+                        }
+                    });
+                });
+            }
         }
-        return result;
     }
 
     @Override
@@ -1543,10 +1661,11 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         List<Map<String,Object>> listMap  = listMap(ids,ExecuteType.TESTING);
         List<KeyMapper> list= listMap.stream().map(m->BeanUtil.toBean(m,KeyMapper.class)).collect(Collectors.toList());
         if(Func.isNotEmpty(listMap)){
+            WbsTreePrivate wtp= this.wbsTreePrivateService.getOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getPKeyId,nodeId));
             List<Map<String,Object>> efMap= this.jdbcTemplate.queryForList("select element_id elementId,formula_id formulaId,scope " +
                     "from m_element_formula_mapping " +
                     "where element_id in(" + list.stream().map(KeyMapper::getFieldId).distinct().map(Func::toStr).collect(Collectors.joining(",")) + ") " +
-                    "and is_deleted=0 " + " and ( scope<2 or (scope =10 and project_id = " + projectId + ") )");
+                    "and is_deleted=0 " + " and ( scope<2 or (scope =10 and project_id = " + projectId + ") or (scope=20 and project_id =" + projectId + " and node_id="+wtp.getId()+"))");
              setFormula(list,efMap);
             if(list.size()>0){
                 return  list;
@@ -2003,8 +2122,48 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         return new HashMap<>();
     }
 
+    @Override
+    public Map<String, FormData> createFormDataByCode(String codes) {
+        if(Func.isNotBlank(codes)) {
+            List<String> codeList = Arrays.asList(codes.split(StringPool.COMMA));
+             String tableNames =  codeList.stream().map(e->e.split(StringPool.COLON)[0]).collect(Collectors.joining(","));
+             /*select d.id,c.tab_ch_name tableChName,d.e_type eType,d.e_name eName,d.e_length eLength,d.e_allow_deviation eAllowDeviation,CONCAT(c.tab_en_name,':',d.e_key) code */
+            List<FormData>  fds =createFormDataByTableName(tableNames);
+            if(fds!=null){
+                return fds.stream().filter(e->codeList.contains(e.getCode())).collect(Collectors.toMap(FormData::getCode,f->f));
+            }
+
+        }
+        return null;
+    }
+
+    @Override
+    public List<FormData> createFormDataByTableName(String tableNames) {
+        List<FormData>  fds =this.getSqlList("select b.id, CONCAT(a.tab_en_name,':',b.e_key) code,a.tab_ch_name tableChName,b.e_name eName ,b.e_allow_deviation eAllowDeviation ,b.e_length eLength,c.dict_value eType " +
+                        "from m_table_info a JOIN m_wbs_form_element b on a.id=b.f_id and b.is_deleted=0  " +
+                        "LEFT JOIN (select dict_key, dict_value from blade_dict where code ='data_type' and parent_id > 0 and is_sealed = 0 and is_deleted = 0 )c on b.e_type=c.dict_key" +
+                        " where  a.tab_en_name in( "+ tableNames+")"
+                ,  FormData.class);
+        return fds;
+    }
 
+    @Override
+    public void loadElementData(List<FormData> curFormDatas, Map<String, List<Long>> tableNamePkeyIdMap) {
+             Map<String,List<FormData>> group = curFormDatas.stream().collect(Collectors.groupingBy(FormData::getTableName,Collectors.toList()));
+             group.forEach((k,v)->{
+                 String ids =tableNamePkeyIdMap.get(k).stream().map(Objects::toString).collect(Collectors.joining(","));
+                 String sql="select id,p_key_id pageId,tab_key tabKey ,key_val value from table_data_info where  p_key_id in("+ids+")";
+                 List<CellDataVo> list= this.getSqlList(sql,CellDataVo.class);
+                 if(list!=null){
+                    Set<String> set= v.stream().map(FormData::getTableName).collect(Collectors.toSet());
+                    Map<String, List<CellDataVo>>  targetGroup=list.stream().filter(e->set.contains(e.getKey())).collect(Collectors.groupingBy(CellDataVo::getKey,Collectors.toList()));
+                    for(FormData fd:v){
+                        fd.setCellDataVoList(targetGroup.get(fd.getKey()));
+                    }
+                 }
+             });
 
+    }
 }